cover

Zustand llegó para destronar a Redux

author photo

Héctorbliss

@hectorbliss


Mira el video si prefieres:

robot logo saying hello

No te quedes atrás: Actualízate

Suscríbete para recibir información sobre nuevos frameworks, updates, eventos, tips, hacks y más.

Redux es ya prácticamente un estándar para manejar estados avanzados y complejos en aplicaciones web del cliente o Single Page Applications (SPA), pero recuerda que en desarrollo web todo es transitorio y siempre hay espacio para descubrir mejores patterns o herramientas que nos ayuden a simplificar u optimizar. Y este es justo el caso de Zustand. 🤯

Zustand es una biblioteca para el manejo de estado —regularmente global o de toda la aplicación— pequeña, rápida y muy escalable. Esto, gracias a su simplicidad; simplicidad que logra gracias a su API que está basada en los Hooks de React. Evitando así, utilizar contextos.

¿Zustand es similar a Redux?

Conceptualmente sí, son muy similares pues ambas herramientas están basadas en un modelo de estado inmutable. Pero, la mayor diferencia con Redux es: que con Redux, es necesario “envolver” — hacer wrapping — nuestra aplicación como lo haríamos con un proveedor de contexto — context provider —, con Zustand esto no es necesario en absoluto. 🥳

Veamos cómo declararíamos un estado con Redux:

// createReduxStore.js // Con Redux necesitamos instalar dos bibliotecas, redux y react-redux import { createStore } from 'redux' import { useSelector, useDispatch } from 'react-redux' // También necesitamos familiarizarnos con una función de tipo reducer const countReducer = (state, action) => { switch (action.type) { case 'suma': return { count: state.count + action.value } // Se devuelve un estado inmutable case 'resta': return { count: state.count - action.value } default: return state } } // Ahora, creamos el "store" que debemos entregar al Context o Wrapper export const createStore = () => createStore(countReducer)

Pero espera, trabajando con Redux, aún no hemos terminado. Necesitamos proveer este store a nuestros componentes a través de un contexto. Algo así:

import React from 'react' import ReactDOM from 'react-dom' // Importamos Provider desde react-redux import { Provider } from 'react-redux' import { App } from './App' // También importamos la función para crear el store import { createStore } from './createReduxStore' // Debemos crear el store en este nivel const store = createStore() //.React 18 const root = ReactDOM.createRoot(document.getElementById('root')) // Hacemos el wrapping de nuestra aplicación y proveemos el store root.render( <Provider store={store}> <App /> </Provider> )

Ahora sí, estaríamos casi listos para utilizar dispatch, y… uff varias cosas más, ¿que rollo no crees?

¿Cómo lo haríamos con Zustand?

Con Zustand definimos múltiples stores, muy al estilo Flux —predecesor de Redux— y aunque parece que tener un solo store es una mejor idea, la separación de concerns a veces ayuda a la modularización y simplificación, mira:

// useCountStore.js // La única herramienta que importamos es la función create de zustand import { create } from 'zustand' // Declaramos un store, que incluye el valor (o estado) y las funciones que lo modifican // Recuerda que este estado es inmutable. // También recuerda que puedes tener un solo store o varios (slices) export const useCountStore = create((set) => ({ count: 0, suma: (value) => set((state) => ({ count: state.count + value })), resta: (value) => set((state) => ({ count: state.count - value })), }))

Y ya, eso es todo. 😎

Ahora podemos importar este store como a cualquier otro Hook, y utilizar su estado inmutable en nuestros componentes, sin necesidad de wrappers o context:

import React from "react"; // Importamos el store que hemos creado con la función create de Zustand import { useCountStore } from "./useCountStore"; export default function App() { // Definimos el estado y los setters (tu decides cómo desconstruir obj o arr) const [count, suma, resta] = useCountStore((state) => [ state.count, state.suma, state.resta, ]); return ( <> <button onClick={resta}>-</button> <span>{count}</span> <button onClick={suma}>+</button> </> ); }

¿Qué tal? ¡Ta perrón! ¿Apoco no? 🤩

Seguramente has escuchado sobre la optimización de los renders, yo te he hablado un poquito de eso en mi video sobre React Hook Form que te dejo en la descripción. Bueno, pues Zustand también nos ayuda con esto; reduciendo al mínimo la necesidad de un re-render.

Zustand está inspirado en Flux

A pesar de que Zustand es una biblioteca opinionated, esto es que toma algunas decisiones por ti, estas desiciones se inspiraron en Flux, pero también en Redux, así que si ya tienes conocimientos en alguna de estas bibliotecas, no tienes prácticamente nada más que aprender. ✅

El pattern más recomendado siempre es tener un solo store como lo hace Redux, pero así como lo harías con Redux Toolkit, puedes separar tu store en slices, pues con Zustand, también es posible.

Zustand es muy versátil, tanto, que si aún quieres conservar el estilo de Redux y adoptarlo poco a poco, siempre puedes definir una función dispatch y una función reducer para trabajar de forma tradicional.

const dispatch = useCountStore((state) => state.dispatch) // La usaríamos de forma tracicional así: dispatch({ type: types.increase, by: 2 })

No te olvides de que Zustand soporta de forma automática las llamadas HTTP asíncronas para mutar un estado en el servidor, otra ventaja sobre Redux, que necesita de un middleware, pero además si los necesitaras, ¡Zustand también soporta middlewares! 🔥

Zustand es una opción seria, madura, potente y muy simple que debes considerar. Hay mucho más que puedo mostrarte de Zustand.

No te olvides de dejarme saber que más te gustaría aprender, para poder crearte más videos que te sean útiles. ¿Qué tal, te gusta Zustand?

Abrazo. Bliss. 🤓

Enlaces relacionados

Zustand docs

https://docs.pmnd.rs/zustand/getting-started/introduction

banner

¿Quieres mantenerte al día sobre los próximos cursos y eventos?

Suscríbete a nuestro newsletter

Jamás te enviaremos spam, nunca compartiremos tus datos y puedes cancelar tu suscripción en cualquier momento 😉

robot logo saying hello
facebook icontwitter iconlinkedin iconinstagram iconyoutube icon

© 2016 - 2023 Fixtergeek