An Interest In:
Web News this Week
- April 19, 2024
- April 18, 2024
- April 17, 2024
- April 16, 2024
- April 15, 2024
- April 14, 2024
- April 13, 2024
Usando Zustand con React JS!
Gestionar el estado es algo necesario en aplicaciones modernas con React JS. Es por eso que hoy te dare una introduccin a "Zustand" una alternativa popular para gestionar tu estado en tus aplicaciones.
Cualquier tipo de Feedback es bienvenido, gracias y espero disfrutes el articulo.
Nota: Este post requiere que sepas las bases de React con TypeScript.
Tabla de contenido
Qu es Zustand?
Ventajas de usar Zustand.
Creando el proyecto.
Creando una store.
Accediendo a la store.Accediendo a multiples estados.
Por qu usamos la funcin shallow?.
Actualizando el estado.
Creando una accin.
Accediendo al estado almacenado en la store.
Ejecutando la accin.Conclusin.
Qu es Zustand?
Zustand es una solucin de gestin de estados pequea, rpida y escalable. Su gestin de estado es centralizada y basada en acciones.
Zustand fue desarrollado por los creadores de Jotai y React-spring's
Puedes usar Zustand tanto en React como en alguna otra tecnologa como Angular, Vue JS o incluso en JavaScript vanilla.
Zustand es una alternativa a otros gestores de estado como Redux, Jotai Recoil, etc.
Ventajas de usar Zustand.
- Menos cdigo repetido (comparado con Redux).
- Documentacin fcil de entender.
- Flexibilidad
- Puedes usar Zustand de la forma simple, con TypeScript, puedes integrar immer para la inmutabilidad o incluso puedes escribir cdigo parecido al patron Redux (reducers y dispatch).
- No envuelve la aplicacin en un proveedor como comnmente se hace en Redux.
- Vuelve a renderizar los componentes solo cuando hay cambios.
Creando el proyecto.
Al proyecto le colocaremos el nombre de: zustand-tutorial
(opcional, tu le puedes poner el nombre que gustes).
npm init vite@latest
Creamos el proyecto con Vite JS y seleccionamos React con TypeScript.
Luego ejecutamos el siguiente comando para navegar al directorio que se acaba de crear.
cd zustand-tutorial
Luego instalamos las dependencias.
npm install
Despus abrimos el proyecto en un editor de cdigo (en mi caso VS code).
code .
Creando una store.
Primero debemos instalar Zustand:
npm install zustand
Una vez instalada la librera, necesitamos crear una carpeta src/store
y dentro de la carpeta agregamos un nuevo archivo llamado bookStore.ts
y dentro de este archivo, crearemos nuestra store.
Primero importamos el paquete de zustand y lo nombramos create
import create from 'zustand';
Luego creamos una constante con el nombre useBookStore (esto es porque zustand usa hooks por debajo y en su documentacin nombre las stores de esta manera).
Para definir la store usamos la funcin create.
import create from 'zustand';export const useBookStore = create();
La funcin create toma una funcin callback como parmetro, que retorna un objeto, para crear la store.
import create from 'zustand';export const useBookStore = create( () => ({}));
Para mejor auto completado, usaremos una interfaz para definir las propiedades de nuestra store, as como las funciones.
Luego establecemos el valor inicial de las propiedades, en este caso la propiedad amount inicialmente sera 40.
import create from 'zustand';interface IBook { amount: number }export const useBookStore = create<IBook>( () => ({ amount: 40 }));
Accediendo a la store.
Para acceder a nuestra store, necesitamos importar dicha store.
En nuestro archivo src/App.tsx
importamos nuestra store.
Sin necesidad de usar proveedores como en Redux, podemos usar nuestra store casi en cualquier lugar ("casi" ya que sigue las reglas de los hooks, ya que la store bsicamente es un hook por debajo).
Bsicamente llamamos a nuestro hook, como cualquier otro, solo que por parmetro debemos indicarle mediante un callback que propiedad queremos obtener del store y gracias al auto completado nos ayuda mucho.
import { useBookStore } from './store/bookStore';const App = () => { const amount = useBookStore(state => state.amount) return ( <div> <h1>Books: {amount} </h1> </div> )}export default App
Accediendo a multiples estados.
Supongamos que tienes mas de un estado en tu store, por ejemplo, agregamos el titulo:
import create from 'zustand';interface IBook { amount: number author: string}export const useBookStore = create<IBook>( () => ({ amount: 40, title: "Alice's Adventures in Wonderland"}));
Para acceder a mas estados podramos hacer lo siguiente:
Caso 1 - Una forma es de manera individual, ir accediendo al estado, creando nuevas constantes.
import { useBookStore } from './store/bookStore';const App = () => { const amount = useBookStore(state => state.amount) const title = useBookStore(state => state.title) return ( <div> <h1>Books: {amount} </h1> </div> )}export default App
Caso 2 - Pero si quieres, tambin puedes crear un nico objeto con multiples estados o propiedades. Y para decirle a Zustand que difunda el objeto superficialmente, debemos pasar la funcin shallow
import shallow from 'zustand/shallow'import { useBookStore } from './store/bookStore';const App = () => { const { amount, title } = useBookStore( (state) => ({ amount: state.amount, title: state.title }), shallow ) return ( <div> <h1>Books: {amount} </h1> <h4>Title: {title} </h4> </div> )}export default App
Aunque lo mejor seria tambin el store colocarlo en un hook aparte si es que llega a crecer demasiado en cuestin de propiedades
Tanto en el caso 1 como el caso 2 los componentes se volvern a renderizar cuando el title y amount cambien.
Por qu usamos la funcin shallow?
En el caso anterior donde accedemos a varios estados de la store, usamos la funcin shallow, por qu?
Por defecto si no usamos shallow, Zustand detecta los cambios con igualdad estricta (old === new), lo cual es eficiente para estados atmicos
const amount = useBookStore(state => state.amount)
Pero en el caso 2, no estamos obteniendo un estado atmico, sino un objeto (pasa lo mismo si usamos un arreglo).
const { amount, title } = useBookStore( (state) => ({ amount: state.amount, title: state.title }), shallow )
Por lo que la igualdad estricta por defecto no seria util en este caso para evaluar objetos y provocando siempre un re-render aunque el objeto no cambie.
Asi que Shallow subir el objeto/arreglo y comparara sus claves, si alguna es diferente se recreara de nuevo y se dispara un nuevo render.
Actualizando el estado.
Para actualizar el state en la store debemos hacerlo creando nuevas propiedades en src/store/bookStore.ts
agregando funciones para actualizar modificar el store.
En el callback que recibe la funcin create, dicha funcin recibe varios parmetros, el primero es la funcin set, el cual nos permitir actualizar la store.
export const useBookStore = create<IBook>(( set ) => ({ amount: 40}));
Creando una accin.
Primero creamos una nueva propiedad para actualizar el amount y se llamara updateAmount el cual recibe un nmero como parmetro.
import create from 'zustand'interface IBook { amount: number updateAmount: (newAmount: number) => void}export const useBookStore = create<IBook>((set) => ({ amount: 40, updateAmount: (newAmount: number ) => {}}));
El el cuerpo de la funcin updateAmount ejecutamos la funcin set mandando un objeto, haciendo referencia a la propiedad a actualizar.
import create from 'zustand'interface IBook { amount: number updateAmount: (newAmount: number) => void}export const useBookStore = create<IBook>( (set) => ({ amount: 40, updateAmount: (newAmount: number ) => set({ amount: newAmount }),}));
La funcin set tambin puede recibir una funcin como parmetro, lo cual es util para obtener el estado anterior.
Opcionalmente hago esparzo todo el estado (suponiendo que tengo ms propiedades) y solo actualizo el estado que necesito, en este caso el amount.
Nota: Lo de esparcir propiedades tmalo en cuenta tambin cuando tus estados sean objetos o arreglos que cambian constantemente.
updateAmount: (newAmount: number ) => set( state => ({ ...state, amount: state.amount + newAmount }))
Tambin puedes hacer acciones asncronas de la siguiente manera y listo!
updateAmount: async(newAmount: number ) => { // to do fetching data set({ amount: newAmount })}
Nota: la funcin set acepta un segundo parmetro booleano, por defecto es falso. En lugar de fusionar, remplazara el modelo del estado. Debe tener cuidado de no borrar partes importantes de su store como las acciones.
updateAmount: () => set({}, true), // clears the entire store, actions included,
Accediendo al estado almacenado en la store.
Para definir el estado usamos la funcin set, pero y si queremos obtener los valores del estado?
Bueno para eso tenemos el segundo parmetro a lado del set, que es get() que nos da acceso al estado.
import create from 'zustand'interface IBook { amount: number updateAmount: (newAmount: number) => void}export const useBookStore = create<IBook>( (set, get) => ({ amount: 40, updateAmount: (newAmount: number ) => { const amountState = get().amount set({ amount: newAmount + amountState }) //is the same as: // set(state => ({ amount: newAmount + state.amount })) },}));
Ejecutando la accin.
Para ejecutar la accin, es simplemente acceder a la propiedad como lo hemos realizado con anterioridad. Y la ejecutamos, mandando los parmetros necesarios, que en este caso es solo un numero.
import { useBookStore } from './store/bookStore';const App = () => { const amount = useBookStore(state => state.amount) const updateAmount = useBookStore(state => state.updateAmount) return ( <div> <h1> Books: {amount} </h1> <button onClick={ () => updateAmount(10) } > Update Amount </button> </div> )}export default App
Conclusin.
Zustand proporciona un fcil acceso y actualizacin del estado, lo que lo convierte en una alternativa amigable a otros gestores de estado.
En opinion personal, Zustand me ha agradado bastante por sus caractersticas antes mencionadas, es una de mis libreras favoritas para gestionar el estado, as como Redux Toolkit. Sin duda deberas de darle una oportunidad para usarla en algn proyecto .
Espero haberte ayudado a entender mejor el como funciona y como usar esta librera,muchas gracias por llegar hasta aqu!
Te invito a que comentes si es que conoces alguna otra caracterstica importante de Zustand o mejores practicas para el cdigo.
Original Link: https://dev.to/franklin030601/usando-zustand-con-react-js-33le
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To