UNPKG

wallant

Version:

Persistant, auto-validate, and computed state container

257 lines (205 loc) 5.24 kB
<p align="center"> <img src="https://i.imgur.com/M1JFh4j.png" width="400"> </p> <p align="center">Persistant, Auto-validate, and computed state container</p> --- <a href="https://github.com/e1016/wallant/blob/master/README.md">Read the documentation in English</a> --- ## instalación `npm i -s wallant` ## uso configuración básica en `/ReactNativeApp/src/Store.js` ```js import Wallant from 'wallant' const store = new Wallant({ persistant: true, // <- el estado persistente viene luego state: { count: 0 }, actions: { add () { this.setState({ count: this.state.count + 1 }) }, sub () { this.setState({ count: this.state.count - 1 }) } } }) export default store ``` Ahora enlazamos el store a nuestro componente ```js // import react and stuffs... import store from './src/Store' class App extends Component { componentDidMount () { store.use(this) } render () { return ( <View style={ styles.container }> <Text>{ store.state.count }</Text> <Button title="add to the counter" onPress={ store.action.add }/> </View> ) } } ``` El store toma el control del componente cuando los enlazas en `componentDidMount`, en otros stores se utiliza un `<Provider>`, pero nosotros queremos mantener un poco más de control sobre que componente accede y cual no al store. --- Ahora, todo hasta este punto es un simple store, pero Wallant puede hacer cosas mas interesante... ## persistant Esta característica guarda el estado automaticamente cada vez que cambia, y persmite restaurarlo cuando la app de inicia de nuevo, solo debes declarar la propiedad `persistant` como `true` en el constructor de `new Wallant`. ```js const store = new Wallant({ // [...] persistant: true, // [...] }) ``` El estado por default es cargado al store al principio. --- ## actions Permite modificar el estado de forma mas simple, `this` hace referencia a `store`. ```js const store = new Wallant({ state: { count: 0 }, actions: { add () { // tip! puedes usar el método `ss` // en lugar de 'setState', no hay // ninguna diferencia, es solo un // shothand this.ss({ count: this.state.count + 1 }) } } }) ``` Puedes hacer tus actions (y cualquier otra cosa) modular, utilizando el `spread operator`. ```js const counterActions = { add () { this.ss({ count: this.state.count + 1 }) }, sub () { this.ss({ count: this.state.count - 1 }) } } const store = new Wallant({ persistant: true, state: { count: 0 }, actions: { ...counterActions, ...otherActions } }) ``` --- ## validate Wallant te prevee una forma fácil de frenar los estados que no cumplen con ciertas condiciones. ```js const store = new Wallant({ persistant: true, state: { count: 0 }, actions: { ...counterActions }, validate: { count (oldValue, newValue) { return newValue < 20 } } }) ``` Para usarlo, declara (en `validate`) un método con el nombre de la propiedad del estado que quieres validar, por ejemplo `count`, este método será usado para validar el valor de count, si el método retorna `false` el `setState` será rechazado en el key `count`, de lo contrario (`true`) se aplicará. Así de fácil. --- ## computed Por último pero no menos importante, los _computed peroperties_, estos puedes hacer tu vida muy fácil, primero declaramos un nodo `computed`. Luego declaramos un método que retorne un valor, por ejemplo: ```js const store = new Wallant({ persistant: true, state: { count: 0 }, actions: { ... }, validate: { ... }, // and computed computed: { sevenTimesCount () { return this.state.count * 7 } } }) ``` `sevenTimesCount` retorna `count` multiplicado por 7, y tu puedes usarlo como unna variable del `state`. ```js render () { return ( <Text>{ store.state.sevenTimesCount }</Text> ) } ``` Wallant crea una propiedad con el nombre de la función, se cuidadoso, porque los `computed values` son indefinidos mientras el store se crea, por lo que si tratas de iterar sobre un valor que no existe, por ejemplo, para filtrar usuarios: ```js [...] computed: { filteredUsers () { return this.state.users .filter(user => user.name.first.startsWith('a')) .map(({ name }) => name.first + ' ' + name.last) } } [...] render () { return ( <View> { store.state.filteredUsers.map(i => [...] ) } </View> ) } ``` Obtienes un error tratando de invocar `.map` de `undefined`, **Como resuelves eso?** - a) declaras en el state el valor, para que tenga un estado inicial. - b) ... ```js render () { return ( <View> { !!store.state.filteredUsers && store.state.filteredUsers.map(i => [...] ) } </View> ) } ``` `!!store.state.property &&` evita que se evalue lo que está justo despues del mismo, y de esa forma se itera hasta que hay valores en la propierda. --- ### Flujo de datos <p align="center"> <img src="https://i.imgur.com/tkJjZZ6.png" alg="Wallant data flow"> </p>