React-Redux: ¿Deberían mantenerse todos los estados de los componentes en la tienda Redux?

89

Digamos que tengo una simple palanca:

Cuando hago clic en el botón, el componente Color cambia entre rojo y azul

Podría lograr este resultado haciendo algo como esto.

index.js

Button: onClick={()=>{dispatch(changeColor())}}
Color: this.props.color ? blue : red

container.js

connect(mapStateToProps)(indexPage)

action_creator.js

function changeColor(){
 return {type: 'CHANGE_COLOR'}
}

reducer.js

switch(){
case 'CHANGE_COLOR':
return {color: true}

pero esto es un montón de código para escribir para algo que podría haber logrado en 5 segundos con jQuery, algunas clases y algo de css ...

Así que supongo que lo que realmente estoy preguntando es, ¿qué estoy haciendo mal aquí?

l2plata
fuente
6
react-redux no se vende como algo más corto que jquery. Definitivamente necesita algo de código para ponerlo en funcionamiento.
zerkms
1
Eche un vistazo aquí: github.com/rackt/redux/issues/1287 hay mucha buena discusión sobre el tema.
m0meni
1
gracias @ AR7 eso es perfecto
l2silver
1
@ l2silver no hay problema. Básicamente, la idea es que si el color de ese componente no le importa a nadie más, simplemente mantenga ese estado interno al componente en sí.
m0meni
2
El problema que AR7 mencionó se ha movido: github.com/reactjs/redux/issues/1287
ptim

Respuestas:

157

Redux está diseñado principalmente para el "estado de la aplicación". Es decir, cualquier cosa relacionada con la lógica de su aplicación. La vista construida sobre él es un reflejo de ese estado, pero no tiene que usar exclusivamente ese contenedor de estado para todo lo que hace.

Simplemente haga estas preguntas: ¿Es este estado importante para el resto de la aplicación? ¿Otras partes de la aplicación se comportarán de manera diferente en función de ese estado? En muchos casos menores, ese no será el caso. Tome un menú desplegable: el hecho de que esté abierto o cerrado probablemente no tendrá ningún efecto en otras partes de la aplicación. Por lo tanto, conectarlo a su tienda probablemente sea excesivo. Ciertamente es una opción válida, pero en realidad no le reporta ningún beneficio. Es mejor usarlo this.statey terminarlo .

En su ejemplo particular, ¿el color de ese botón está activado para hacer alguna diferencia en otras partes de la aplicación? Si se trata de una especie de activación / desactivación global para la mayor parte de su aplicación, definitivamente pertenece a la tienda. Pero si solo está cambiando el color de un botón cuando hace clic en el botón, puede dejar el estado de color definido localmente. La acción de hacer clic en el botón puede tener otros efectos que requieran un envío de acción, pero eso es independiente de la simple pregunta de qué color debería ser.

En general, intente mantener el estado de su aplicación lo más pequeño posible. No tienes que meter todo ahí. Hágalo cuando sea necesario o tiene mucho sentido mantener algo allí. O si le facilita la vida al usar Dev Tools. Pero no sobrecargue demasiado su importancia.

Tim Dorr
fuente
Oye, sé que nunca habrá una respuesta definitiva para esta pregunta, pero creo que tu lógica es muy sólida aquí
l2silver
3
Para ser honesto, realmente no entiendo cuál es el punto de usar ese flux / redux en absoluto. ¿Cuál fue el problema con el modelo impulsado por eventos?
jayarjo
En mi opinión, no es la respuesta perfecta. Depende. Almacenar el estado de la interfaz de usuario en el estado de reacción hará que la tienda redux quede limpia, pero terminará siendo un componente no funcional que es difícil de probar. Si bien almacenar el estado de la interfaz de usuario en el estado de reacción agregará muchos esfuerzos en el desarrollo, porque tenemos que escribir reductores adicionales. Sin embargo, hay muchos paquetes que pueden ayudarlo a que su estado de interfaz de usuario sea ​​mucho más fácil para reducir la tienda, consulte redux.js.org/docs/faq/OrganizingState.html para obtener más detalles.
Ron
19

Preguntas frecuentes de Redux: Organizar el estado de
esta parte del documento oficial de redux respondió bien a su pregunta.

Usar el estado del componente local está bien . Como desarrollador, es su trabajo determinar qué tipos de estado componen su solicitud y dónde debe vivir cada parte del estado. Encuentre un equilibrio que funcione para usted y sígalo.

Algunas reglas generales comunes para determinar qué tipo de datos deben colocarse en Redux:

  • ¿A otras partes de la aplicación les importan estos datos?
  • ¿Necesita poder crear más datos derivados basados ​​en estos datos originales?
  • ¿Se utilizan los mismos datos para controlar varios componentes?
  • ¿Tiene algún valor para usted poder restaurar este estado a un punto dado en el tiempo (es decir, depuración del viaje en el tiempo)?
  • ¿Desea almacenar en caché los datos (es decir, usar lo que está en estado si ya está allí en lugar de volver a solicitarlo)?
chuck911
fuente
6

Con el propósito de resaltar el gran enlace proporcionado por @ AR7, y porque ese enlace se movió hace un tiempo:

Use React para un estado efímero que no le importa a la aplicación globalmente y que no mute de manera compleja. Por ejemplo, un conmutador en algún elemento de la interfaz de usuario, un estado de entrada de formulario. Use Redux para el estado que importa a nivel mundial o está mutado de manera compleja. Por ejemplo, usuarios almacenados en caché o un borrador de publicación.

A veces querrá pasar del estado Redux al estado React (cuando almacenar algo en Redux se vuelve incómodo) o al revés (cuando más componentes necesitan tener acceso a algún estado que solía ser local).

La regla general es: haz lo que sea menos incómodo.

Dan Abramov: https://github.com/reactjs/redux/issues/1287#issuecomment-175351978

ptim
fuente
-8

Sí, vale la pena esforzarse por almacenar todos los estados de los componentes en Redux . Si lo hace, se beneficiará de muchas funciones de Redux, como la depuración de viajes en el tiempo y los informes de errores repetibles. Si no lo hace, esas funciones podrían quedar completamente inutilizables .

Siempre que no almacene un cambio de estado de componente en Redux, ese cambio se perderá por completo de la pila de cambios de Redux y la interfaz de usuario de su aplicación no estará sincronizada con la tienda. Si esto no es importante para usted, entonces pregúntese por qué usar Redux. ¡Su aplicación será menos compleja sin él!

Por motivos de rendimiento, es posible que desee recurrir a this.setState()cualquier cosa que envíe muchas acciones repetidamente. Por ejemplo: almacenar el estado de un campo de entrada en Redux cada vez que el usuario escribe una clave puede resultar en un rendimiento deficiente. Puede resolver esto tratándolo como una transacción: una vez que la acción del usuario está "confirmada", guarde el estado final en Redux.

Su publicación original menciona que el método Redux es "una gran cantidad de código para escribir". Sí, pero puede usar abstracciones para patrones comunes, como el estado del componente local.

kumar303
fuente
La depuración mejorada es un objetivo útil y una buena característica de redux, pero creo que la relación señal / ruido también es importante. Uno podría registrar cada variable en una base de código, pero eso agregaría una gran cantidad de código adicional haciendo que el código real sea más difícil de leer y el registro sería difícil de buscar. Creo que lo mismo se aplica al uso de redux. Tener todo el estado en redux puede mejorar la depuración, pero existe un costo en código adicional y abstracciones que pueden hacer que el código sea más difícil de leer e incluso hacer que algunas tareas de depuración sean más difíciles. (Y cuando las herramientas de desarrollo redux fallan, muchas de las ganancias de depuración se pierden.)
JD Sandifer
1
Entonces, ¿por qué usar Redux? Si no pone todo en Redux, pierde todas las funciones, como devtools. Realmente es todo o nada. Si usa setState () para un menú desplegable como en la respuesta principal de esta publicación, no puede usar devtools para depurar cualquier problema que sus usuarios puedan encontrar dentro del menú desplegable. Es peor cuando usa setState () para una superposición porque no hay forma de viajar en el tiempo antes y después de que se muestre la superposición. Rociar setState () aquí y allá es muy propenso a errores porque el desarrollador tiene que pensar constantemente en lo que podría fallar.
kumar303
Como respuesta más específica, registrar cada variable en una base de código no es una metáfora útil, ya que la pregunta es si usar this.setState()o dispatch(action...). No es necesario usarlo en this.setState()todas partes, pero cuando sea necesario, mi sugerencia es usar Redux en su lugar para el 99% de los casos, recurriendo al this.setState()1% en función de las preocupaciones de rendimiento.
kumar303
El registro de cada variable me parece análogo a poner todo en Redux e igualmente desaconsejable como regla general. Dejar algunas cosas fuera de Redux no niega las características de todo lo que está en Redux siempre que el estado esté separado. Es decir, todavía puedo depurar la lógica de mi llamada API que se canaliza a través de Redux incluso si el estado de un cuadro de selección no lo es. El OP tiene un punto: requiere más código en varios lugares para usar Redux y tal vez eso no esté justificado en el ejemplo específico que enumeraron.
JD Sandifer
En realidad, es posible que no pueda depurar la lógica de su API. Ese es mi punto. Es realmente difícil prever los escenarios en los que romperá el viaje en el tiempo, por lo que es mejor poner todo el estado (incluido el estado del cuadro de selección) en Redux hasta que haya un problema de rendimiento.
kumar303