tojs react meaning inmutabilidad immutable array javascript immutable.js redux

javascript - react - ¿Cómo usar Immutable.js con redux?



react redux (5)

Redux marco de Redux está utilizando reducers para cambiar el estado de la aplicación en respuesta a una acción.

El requisito clave es que un reductor no puede modificar un objeto de estado existente; debe producir un nuevo objeto.

Mal ejemplo :

import { ACTIVATE_LOCATION } from ''./actions''; export let ui = (state = [], action) => { switch (action.type) { case ACTIVATE_LOCATION: state.activeLocationId = action.id; break; } return state; };

Buen ejemplo :

import { ACTIVATE_LOCATION } from ''./actions''; export let ui = (state = [], action) => { switch (action.type) { case ACTIVATE_LOCATION: state = Object.assign({}, state, { activeLocationId: action.id }); break; } return state; };

Este es un buen caso de uso para Immutable.js .



Immutable.js debe usarse en cada reductor según sea necesario, p. Ej.

import { ACTIVATE_LOCATION } from ''./actions''; import Immutable from ''immutable''; export let ui = (state, action) => { switch (action.type) { case ACTIVATE_LOCATION: state = Immutable .fromJS(state) .set(''activeLocationId'', action.id) .toJS(); break; } return state; };

Sin embargo, hay muchos gastos generales en este ejemplo: cada vez que se invoca una acción reductora, tiene que convertir el objeto JavaScript en una instancia de Inmutable, mutar el objeto resultante y volverlo a convertir en objeto JavaScript.

Un mejor enfoque es hacer que el estado inicial sea una instancia de Inmutable:

import { ACTIVATE_LOCATION } from ''./actions''; import Immutable from ''immutable''; let initialState = Immutable.Map([]); export let ui = (state = initialState, action) => { switch (action.type) { case ACTIVATE_LOCATION: state = state.set(''activeLocationId'', action.id); break; } return state; };

De esta manera, solo necesita convertir el estado inicial a una instancia de onza Immutable . Luego, cada reductor lo tratará como una instancia de Immutable y lo pasará por la línea como una instancia de Immutable . El problema es que ahora necesita convertir todo el estado a JavaScript antes de pasar los valores al contexto de la vista.

Si está realizando múltiples mutaciones de estado en un reductor, es posible que desee considerar mutaciones por lotes utilizando .withMutations .

Para simplificar las cosas, he desarrollado una biblioteca redux-immutable . Proporciona la función combineReducers que es equivalente a la función del mismo nombre en el paquete redux, excepto que espera que el estado inicial y todos los reductores funcionen con el objeto Immutable.js .


La respuesta aceptada no debe ser la respuesta aceptada. Debe inicializar el estado usando inmutable y luego (como se mencionó anteriormente) usar redux-immutablejs

const initialState = Immutable.fromJS({}) // or Immutable.Map({}) const store = _createStore(reducers, initialState, compose( applyMiddleware(...middleware), window.devToolsExtension ? window.devToolsExtension() : f => f ));

Que usar los combineReducers de redux-immutablejs

Consejo adicional: el uso de react-router-redux funciona bastante bien, por lo que si desea agregar esto, reemplace el reductor de react-router-redux con esto:

import Immutable from ''immutable''; import { UPDATE_LOCATION } from ''react-router-redux''; let initialState; initialState = Immutable.fromJS({ location: undefined }); export default (state = initialState, action) => { if (action.type === UPDATE_LOCATION) { return state.merge({ location: action.payload }); } return state; };

Solo importe esto en su reductor de raíz

Esto también se indica en la documentación de redux-immutablejs


Si solo está buscando una manera fácil de realizar actualizaciones sin mutación, mantengo una biblioteca: https://github.com/substantial/updeep que, en mi opinión, es una buena manera de hacerlo con redux .

updeep permite trabajar con jerarquías de objetos regulares (congeladas), para que pueda realizar la desestructuración, ver objetos en los registros y el depurador, etc. También tiene una API potente que permite la actualización por lotes. No será tan eficiente como Immutable.js para conjuntos de datos grandes porque clona objetos si es necesario.

Aquí hay un ejemplo (pero revise aquellos en el archivo README para más información):

import { ACTIVATE_LOCATION } from ''./actions''; import u from ''updeep''; export let ui = (state = [], action) => { switch (action.type) { case ACTIVATE_LOCATION: state = u({ activeLocation: action.id }, state); break; } return state; };


Tomando tu buen ejemplo con Immutable

import { ACTIVATE_LOCATION } from ''./actions''; import { Map } from ''immutable''; const initialState = Map({}) export let ui = (state = initialState, action) => { switch (action.type) { case ACTIVATE_LOCATION: return state.set(''activeLocationId'', action.id); default: return state; } };