Cómo restablecer el estado de Redux con un reductor de raíz

Introducción
¿Alguna vez tuviste que restablecer el estado inicial de Redux en tus reductores? Restablecer el estado es algo que muchas aplicaciones necesitan hacer. Un ejemplo típico de cuándo se debe restablecer el estado de la aplicación podría ser cuando el usuario cierra la sesión.
En este artículo, aprenderá cómo centralizar el restablecimiento del estado, la lógica de restablecimiento por reductor y cómo excluir a los reductores del restablecimiento.
Prerrequisitos
Para seguir este tutorial, necesitarás:
- Conocimientos básicos de React y Redux. Puedes consultar esta publicación si estás empezando a usar Redux.
Este tutorial fue verificado con redux
v4.1.0.
Comprender las limitaciones deRESET_APP
El enfoque más ingenuo es agregar una RESET_APP
condición a todos los reductores.
Consideremos un users
reductor con la siguiente forma:
const usersDefaultState = [];const users = (state = usersDefaultState, { type, payload }) = { switch (type) { case 'ADD_USER': return [...state, payload]; default: return state; }};
Luego agregarías un RESET_APP
caso al conmutador para devolver usersDefaultState
:
const usersDefaultState = [];const users = (state = usersDefaultState, { type, payload }) = { switch (type) { case 'RESET_APP': return usersDefaultState; case 'ADD_USER': return [...state, payload]; default: return state; }};
Esto es aceptable para uno o dos reductores, pero en cualquier aplicación del mundo real, eso llevaría a repetir el mismo código para cada reductor, y lo más probable es que tengas muchos de ellos:
const usersDefaultState = [];const users = (state = usersDefaultState, { type, payload }) = { switch (type) { case 'RESET_APP': return usersDefaultState; case 'ADD_USER': return [...state, payload]; default: return state; }};const articlesDefaultState = [];const articles = (state = articlesDefaultState, { type, payload }) = { switch (type) { case 'RESET_APP': return articlesDefaultState; case 'ADD_ARTICLE': return [...state, payload]; default: return state; }};
¿ Recuerdas el principio DRY (Don’t Repeat Yourself)? Bueno, este código no cumple realmente con ese principio y eso es algo que nosotros, como desarrolladores, deberíamos intentar evitar.
Centralizando el restablecimiento del Estado
El truco para reutilizar la lógica para restablecer la aplicación en un solo lugar es crear un reductor raíz sobre el reductor raíz de la aplicación. Es decir, un reductor sobre los reductores donde se verifica esa condición y se aplica si es necesario.
Por lo general, usarías la combineReducers
función para crear un único reductor raíz para tu tienda redux:
import { combineReducers } from 'redux';const usersDefaultState = [];const users = (state = usersDefaultState, { type, payload }) = //...const articlesDefaultState = [];const articles = (state = articlesDefaultState, { type, payload }) = //...const allReducers = combineReducers({ users, articles});
En este caso, allReducers
es el reductor raíz de tu aplicación el que pasarás a createStore
la función de Redux.
Para crear un reductor raíz envolvente sobre ese, solo necesitamos definir una función que llame a ese reductor raíz:
const rootReducer = (state, action) = { return allReducers(state, action);}
En este momento, rootReducer
actúa como una función que se encuentra entre la allReducers
llamada. Justo antes de esa llamada es donde podemos agregar una funcionalidad común que se aplicará antes de la llamada de los reductores. Y para restablecer la aplicación, podríamos simplemente pasar un conjunto de estados a undefined
:
const rootReducer = (state, action) = { if (action.type === 'RESET_APP') { state = undefined; } return allReducers(state, action);}
Espera, ¿qué? ¿Por qué eso reiniciaría la aplicación? Bueno, si analizamos la definición del reductor:
const users = (state = usersDefaultState, { type, payload }) = //...
Verá que el valor predeterminado para el state
parámetro es usersDefaultState
en este caso, y el parámetro predeterminado de una función se aplica cuando y solo cuando el valor del parámetro recibido es undefined
(ni siquiera null
, solo undefined
). Es por eso que el estado que recibirán todos los reductores es el estado predeterminado.
Espera, ¿no estamos mutando el estado? No, estamos cambiando la referencia del estado a undefined
, no mutándolo. Recuerda que mutar el estado va en contra de los principios de Redux.
Uso de la lógica de reinicio por reductor
La aplicación de la lógica de reinicio centralizada mediante a rootReducer
no impide tener una funcionalidad personalizada para la RESET_APP
acción en otros reductores.
Por ejemplo, digamos que el articles
reductor debe devolver un estado distinto al predeterminado cuando RESET_APP
se activa:
const articles = (state = articlesDefaultState, { type, payload }) = { switch (type) { case "RESET_APP": return "App is reset"; case "ADD_ARTICLE": return [...state, payload]; default: return state; }};
El punto es que, de manera predeterminada, harás que todos los reductores devuelvan su estado predeterminado y solo tendrás un comportamiento de reinicio personalizado cuando lo necesites.
Exclusión de reductores para que no se restablezcan
Podría suceder que no queramos restablecer algunos reductores específicos. Podríamos evitarlo manteniendo la porción del estado que queremos excluir.
Por ejemplo, si desea excluir el articles
reductor del reinicio:
const rootReducer = (state, action) = { if (action.type === 'RESET_APP') { const { articles } = state; state = { articles }; } return allReducers(state, action);};
¿Qué está pasando aquí? Bueno, la combineReducers
función combina los reductores y pasa la parte correspondiente del estado, de modo que cada reductor tiene solo su parte del estado en su ámbito.
En este caso, al seleccionar el articles
fragmento del estado con state = { articles }
, la función allReducers
pasará state.articles
al articles
reductor y state.users
al users
reductor. Como state.users
es undefined
y state.articles
no es, solo se reiniciará el reductor del usuario.
Conclusión
En este artículo, aprendió cómo centralizar el restablecimiento del estado, la lógica de restablecimiento por reductor y cómo excluir a los reductores del restablecimiento.
Generalmente hay varias formas de evitar la duplicación de código, pero seguir el principio DRY hace que su código sea más comprensible y fácil de mantener.
Deja una respuesta