¡DEJA de usar Redux ciegamente!
Como desarrollador perezoso, no me lo creí. Sentía que usar el estado predeterminado y context era mucho mejor. Había demasiado boilerplate en Redux y la separación de responsabilidades, aunque válida, podría lograrse fácilmente usando un hook personalizado. También usábamos redux-saga para interactuar con el backend. Lo que me parecía otra carga completamente innecesaria.
Pero estaba comenzando mi carrera, así que decidí darle una oportunidad justa. Usé redux y redux-saga durante aproximadamente un año. Y mis argumentos en su contra solo se intensificaron. Seguía preguntando: ¿por qué usamos redux? Y mis superiores me daban respuestas como:
- Hace el código más testeable
- Separa la lógica de negocios de la lógica de componentes
- Se recomienda no usar useState para tipos de datos complejos (como objetos o arrays de objetos)
- redux-saga te puede dar más control sobre el estado de la API
- Podrías usar context, pero ¿cuántos context providers envolverías tu app en?
A todo esto, tenía respuestas, pero no muy convincentes. Quiero decir, redux era redux —usado por millones de desarrolladores y grandes empresas— y yo solo era un ingeniero de software junior frustrado por el boilerplate.
Ahora, después de haber trabajado como Líder de Equipo, puedo decir con confianza que mis superiores estaban completamente equivocados, y ellos estarían de acuerdo. Mi razón para escribir este artículo es que incluso hoy en día, hay tantas empresas que usan redux y lo aceptan como un estándar ciego. ¡Necesitamos parar y mirar las alternativas que tenemos!
Para empezar, entendamos más claramente cuál es mi problema con redux. Aquí está la cantidad de código que necesitaríamos escribir para un estado count simple usando redux. Obviamente, esto es solo un ejemplo —no muestra una aplicación real, pero es bastante efectivo.
// src/actionConstants.js
const ACTION_CONSTANTS = {
INCREMENT_COUNT: "INCREMENT_COUNT",
DECREMENT_COUNT: "DECREMENT_COUNT",
RESET_COUNT: "RESET_COUNT"
}
// src/store/countStore/reducer.js
const initialState = { count: 0 }
export const countReducer = (state = initialState, action) => {
switch (action.type){
case ACTION_CONSTANTS.INCREMENT_COUNT:
return { count: state.count + 1 };
case ACTION_CONSTANTS.DECREMENT_COUNT:
return { count: state.count - 1 };
case ACTION_CONSTANTS.RESET_COUNT:
return initialState;
}
}
// src/store/countStore/selectors.js
export const useCountReducer = () => {
return useSelector(store => store.countReducer)
}
// src/store/countStore/actions.js
export const incrementCount = () => ({
type: ACTION_CONSTANTS.INCREMENT_COUNT
})
export const decrementCount = () => ({
type: ACTION_CONSTANTS.DECREMENT_COUNT
})
export const resetCount = () => ({
type: ACTION_CONSTANTS.RESET_COUNT
})
// src/store/index.js
const rootReducer = combineReducers({ countReducer: countReducer, ... });
¿No es simplemente criminal? Esto aún no incluye el código que va en tu saga o thunk cuando interactúas con el backend —esto es solo para una variable de estado compartida regularmente— count. Imagina la cantidad de problemas por los que tienes que pasar solo para hacer un cambio menor en la lógica: saltando de un archivo a otro y asegurándote de que esos cambios sean consistentes en todos los archivos.
Redux está pensado para ser un almacén global. Es para ser usado para compartir estado en todos los componentes de tu app. Pero el problema es que cuando las empresas comienzan a usar redux, tienden a almacenar todo su estado de API (que 'podría' necesitar compartirse en el futuro) usando redux. Esto tiene sentido para un proyecto donde muchas personas van a trabajar —y quieres tener una forma consistente de escribir código. Sin embargo, aumenta el tamaño del código y reduce su mantenibilidad drásticamente.
Aunque han introducido redux-toolkit y eso limpia un poco el código —todavía no se compara con muchas otras librerías que hacen el trabajo mucho mejor. Aquí está el stack que usamos en My Next Developer:
React-Query: Uso react-query para manejar todos los estados de API en mis apps. Internamente gestiona estados de carga, error y éxito para todas las llamadas a API, cachea resultados para evitar re-consultas y hace muy fácil acceder a los datos en múltiples componentes. Esta es una herramienta hermosa —una vez que la uses, te prometo que no volverás atrás. La documentación simple y la implementación basada en hooks la hacen muy limpia. Aquí hay una popular lista de reproducción de YouTube de React Query Tutorial for Beginners por Codevolution para aprender react-query.
Context: Hay muy pocos casos donde tenemos un estado global no basado en API que necesite ser compartido en múltiples componentes. En esos pocos casos, context es lo más fácil de implementar. Tampoco añade innecesariamente otra librería a la mezcla.
¿No estás de acuerdo? ¡Me encantaría escuchar tus opiniones!


