reactjs - inducidas - Redux: ¿Por qué evitar las mutaciones es una parte tan fundamental de su uso?
tipos de mutaciones (5)
Soy nuevo en Redux, y realmente estoy tratando de tener una idea general del uso de la programación funcional para hacer que los datos unidireccionales sean más elegantes.
De la manera que lo veo, cada reductor está tomando el estado anterior, creando un nuevo estado sin mutar el estado anterior y luego pasando el nuevo estado al siguiente reductor para hacer lo mismo.
Entiendo que no causar efectos secundarios nos ayuda a obtener los beneficios de un flujo de datos unidireccional.
Simplemente no entiendo lo que es tan importante acerca de no mutar el estado anterior.
Lo único en lo que puedo pensar es en el "viaje en el tiempo" sobre el que he leído porque, si se mantiene en todos los estados, puede realizar y "deshacer".
Pregunta:
¿Hay otras razones por las que no queremos mutar el estado anterior en cada paso?
La clave del mantra de "no mutaciones" es que si no puede mutar el objeto, se le obliga a crear uno nuevo (con las propiedades del objeto original más los nuevos). Para actualizar los componentes cuando se envía una acción, Redux comprueba si el objeto es diferente, no si las propiedades han cambiado, por lo que:
- Si crea un nuevo objeto , Redux verá que el objeto no es el mismo, por lo que activará las actualizaciones de los componentes .
- Si muta el objeto que ya está en la tienda (por ejemplo, agregando o cambiando una propiedad), Redux no verá el cambio , por lo que no actualizará los componentes.
Redux verifica si el objeto anterior es el mismo que el nuevo objeto al comparar las ubicaciones de memoria de los dos objetos. Si muta la propiedad del objeto antiguo dentro de un reductor, el "nuevo estado" y el "estado antiguo" apuntarán al mismo objeto y Redux deducirá que nada ha cambiado.
Sin razones. No hay ninguna razón fundamental por la que la optimización de "renderización pura" de ComponentUpdate no pueda funcionar con contenedores de estado mutables. Esta biblioteca lo hace, por ejemplo.
https://github.com/Volicon/NestedReact
Con datos inmutables, la referencia a la propia estructura de datos se puede utilizar como token de versión. Así, comparando las referencias estás comparando las versiones.
Con los datos mutables, tendrá que introducir (y comparar) tokens de versión por separado, lo que es difícil de hacer manualmente pero se puede lograr fácilmente con objetos inteligentes "observables".
Soy bastante nuevo en Redux (y React.js) también, pero esto es lo que entiendo de aprender estas cosas.
Hay varias razones por las cuales el estado inmutable se elige sobre el mutable. En primer lugar, el seguimiento de mutaciones es bastante difícil. Por ejemplo, cuando está utilizando una variable en varios fragmentos de código y la variable se puede modificar en cada uno de estos lugares, debe manejar cada cambio y sincronizar los resultados de la mutación. Este enfoque en muchos casos conduce a flujos de datos bidireccionales. Las piezas de datos fluyen hacia arriba y hacia abajo a través de las funciones, variables, etc. El código comienza a ser contaminado por if-else
construcciones if-else
que son las únicas responsables de manejar los cambios de estado. Cuando agrega algunas llamadas asíncronas, los cambios de estado pueden ser incluso más difíciles de rastrear. Por supuesto, podemos suscribirnos a eventos de datos (por ejemplo, Object.observe
), pero puede llevar a la situación de que alguna parte de la aplicación que perdió el cambio no esté sincronizada con otra parte de su programa.
El estado inmutable lo ayuda a implementar un flujo de datos unidireccional que lo ayuda a manejar todos los cambios. En primer lugar, todos los datos fluyen de arriba a abajo. Eso significa que todos los cambios que se aplicaron al modelo principal se aplican a los componentes inferiores. Siempre puede estar seguro de que el estado es el mismo en todos los lugares de la aplicación, ya que solo se puede cambiar desde un lugar en el código: los reductores. También hay una cosa que vale la pena mencionar: puede reutilizar los datos en varios componentes. El estado no se puede cambiar (se puede crear uno nuevo), por lo que es bastante seguro usar la misma pieza de datos en varios lugares.
Puede encontrar más información sobre las ventajas y desventajas de la mutabilidad (y sobre la razón por la que se eligió como un enfoque principal de Redux) aquí:
Trabajar con estructuras de datos inmutables puede tener un impacto positivo en el rendimiento, si se hace correctamente. En el caso de React, el rendimiento a menudo consiste en evitar la representación innecesaria de su aplicación, si los datos no cambiaron.
Para lograrlo, necesita comparar el siguiente estado de su aplicación con el estado actual. Si los estados difieren: re-render. De lo contrario no.
Para comparar estados, necesitas comparar los objetos en el estado para la igualdad. En los objetos JavaScript antiguos, es necesario realizar una comparación profunda para ver si ha cambiado alguna propiedad dentro de los objetos.
Con objetos inmutables, no necesitas eso.
immutableObject1 === immutableObject2
básicamente hace el truco. O si está utilizando una lib como Immutable.is(obj1, obj2)
.
En términos de reacción, podría usarlo para el método shouldComponentUpdate
, como lo hace el popular PureRenderMixin
.
shouldComponentUpdate(nextProps, nextState) {
return nextState !== this.state;
}
Esta función evita la representación cuando el estado no cambió.
Espero, que contribuya al razonamiento detrás de objetos inmutables.