React-Redux: tous les états des composants doivent-ils être conservés dans Redux Store


89

Disons que j'ai une bascule simple:

Lorsque je clique sur le bouton, le composant Couleur passe du rouge au bleu

Je pourrais obtenir ce résultat en faisant quelque chose comme ça.

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}

mais c'est énormément de code à écrire pour quelque chose que j'aurais pu réaliser en 5 secondes avec jQuery, certaines classes et quelques css ...

Donc je suppose que ce que je demande vraiment, c'est ce que je fais de mal ici?


6
react-redux n'est pas vendu comme quelque chose de plus court que jquery. Il a certainement besoin d'un peu de code pour le rendre opérationnel.
zerkms

1
Jetez un œil ici: github.com/rackt/redux/issues/1287 il y a beaucoup de bonnes discussions sur le sujet.
m0meni

1
merci @ AR7 thats perfect
l2silver

1
@ l2silver pas de problème. Fondamentalement, l'idée est que si la couleur de ce composant n'a pas d'importance pour quelqu'un d'autre, gardez simplement cet état interne au composant lui-même.
m0meni

2
le problème mentionné par AR7 a été déplacé: github.com/reactjs/redux/issues/1287
ptim

Réponses:


154

Redux est principalement destiné à «l'état de l'application». Autrement dit, tout ce qui concerne la logique de votre application. La vue construite dessus est le reflet de cet état, mais n'a pas à utiliser exclusivement ce conteneur d'état pour tout ce qu'il fait.

Posez simplement ces questions: cet état est-il important pour le reste de l'application? Les autres parties de l'application se comporteront-elles différemment en fonction de cet état? Dans de nombreux cas mineurs, ce ne sera pas le cas. Prenez un menu déroulant: le fait qu'il soit ouvert ou fermé n'aura probablement aucun effet sur les autres parties de l'application. Donc, le câbler à votre magasin est probablement exagéré. C'est certainement une option valable, mais ne vous rapporte pas vraiment d'avantages. Vous feriez mieux de l'utiliser this.stateet de l'appeler un jour.

Dans votre exemple particulier, la couleur de ce bouton est-elle activée pour faire une différence dans d'autres parties de l'application? S'il s'agit d'une sorte de bascule marche / arrêt globale pour une grande partie de votre application, elle appartient définitivement au magasin. Mais si vous ne faites que basculer une couleur de bouton lorsque vous cliquez sur le bouton, vous pouvez laisser l'état de couleur défini localement. L'action de cliquer sur le bouton peut avoir d'autres effets qui nécessitent une distribution d'action, mais cela est distinct de la simple question de savoir quelle couleur il devrait être.

En général, essayez de garder l'état de votre application aussi petit que possible. Vous n'êtes pas obligé de tout pousser là-dedans. Faites-le quand vous devez ou il est très logique de garder quelque chose là-bas. Ou si cela vous facilite la vie lorsque vous utilisez les outils de développement. Mais ne surchargez pas trop son importance.


Hé, je sais qu'il n'y aura jamais de réponse définitive à cette question, mais je pense que votre logique est très solide ici
l2silver

3
Pour être honnête, je ne comprends pas vraiment quel est l'intérêt d'utiliser ce truc flux / redux. Quel était le problème avec le modèle événementiel?
jayarjo

IMO, ce n'est pas la réponse parfaite. Ça dépend. Le stockage de l'état de l'interface utilisateur dans l'état de réaction rendra le magasin redux propre, mais il se terminera par un composant non fonctionnel qui est difficile à tester. Le stockage de l'état de l'interface utilisateur dans l'état de réaction ajoutera beaucoup d'efforts sur le développement, car nous devons écrire des réducteurs supplémentaires. Cependant, il existe de nombreux packages qui peuvent vous aider à rendre votre état d' interface utilisateur beaucoup plus facile à stocker en redux, consultez redux.js.org/docs/faq/OrganizingState.html pour plus de détails.
Ron

19

FAQ Redux: État d'organisation
Cette partie de la documentation officielle de redux a bien répondu à votre question.

L'utilisation de l'état du composant local est très bien . En tant que développeur, il est de votre devoir de déterminer quels types d'état composent votre application et où chaque élément d'état doit vivre. Trouvez un équilibre qui vous convient et allez-y.

Quelques règles empiriques courantes pour déterminer le type de données à mettre dans Redux:

  • Les autres parties de l'application se soucient-elles de ces données?
  • Avez-vous besoin de pouvoir créer d'autres données dérivées basées sur ces données d'origine?
  • Les mêmes données sont-elles utilisées pour piloter plusieurs composants?
  • Est-il utile de pouvoir restaurer cet état à un moment donné (c'est-à-dire, débogage de voyage dans le temps)?
  • Voulez-vous mettre en cache les données (c'est-à-dire utiliser ce qui est dans l'état s'il est déjà là au lieu de le redemander)?

6

Dans le but de mettre en évidence l'excellent lien fourni par @ AR7, et parce que ce lien a été déplacé il y a quelque temps:

Utilisez React pour un état éphémère qui n'a pas d'importance pour l'application globalement et qui ne mute pas de manière complexe. Par exemple, une bascule dans un élément d'interface utilisateur, un état d'entrée de formulaire. Utilisez Redux pour un état qui compte globalement ou qui subit des mutations complexes. Par exemple, les utilisateurs mis en cache ou un post-projet.

Parfois, vous voudrez passer de l'état Redux à l'état React (lorsque le stockage de quelque chose dans Redux devient gênant) ou l'inverse (lorsque plus de composants doivent avoir accès à un état qui était local).

La règle d'or est la suivante: faites ce qui est moins gênant.

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


-7

Oui, cela vaut la peine de s'efforcer de stocker tous les états des composants dans Redux . Si vous le faites, vous bénéficierez de nombreuses fonctionnalités de Redux telles que le débogage du voyage dans le temps et les rapports de bogues rejouables. Sinon, ces fonctionnalités pourraient être complètement inutilisables .

Chaque fois que vous ne stockez pas une modification d'état de composant dans Redux, cette modification est complètement perdue de la pile de modifications Redux et l'interface utilisateur de votre application sera désynchronisée avec le magasin. Si cela n'est pas important pour vous, demandez-vous pourquoi utiliser Redux? Votre application sera moins complexe sans elle!

Pour des raisons de performances, vous souhaiterez peut-être vous rabattre sur this.setState()tout ce qui enverrait plusieurs actions à plusieurs reprises. Par exemple: le stockage de l'état d'un champ de saisie dans Redux chaque fois que l'utilisateur tape une clé peut entraîner de mauvaises performances. Vous pouvez résoudre ce problème en le traitant comme une transaction: une fois l'action de l'utilisateur "validée", enregistrez l'état final dans Redux.

Votre message original mentionne comment la méthode Redux est un «enfer de beaucoup de code à écrire». Oui, mais vous pouvez utiliser des abstractions pour des modèles courants tels que l'état des composants locaux.


L'amélioration du débogage est un objectif utile et une fonctionnalité intéressante de redux, mais je pense que le rapport signal sur bruit est également important. On pourrait enregistrer chaque variable dans une base de code, mais cela ajouterait beaucoup de code supplémentaire rendant le code réel plus difficile à lire et la journalisation serait difficile à parcourir. Je pense que la même chose s'applique à l'utilisation de redux. Le fait d'avoir tous les états dans redux peut améliorer le débogage, mais il y a un coût en code supplémentaire et en abstractions qui peuvent rendre le code plus difficile à lire et même rendre certaines tâches de débogage plus difficiles. (Et lorsque les outils de développement redux plantent, la plupart des gains de débogage sont perdus.)
JD Sandifer

1
Alors pourquoi utiliser Redux? Si vous ne mettez pas tout dans Redux, vous perdez toutes les fonctionnalités, telles que devtools. C'est vraiment tout ou rien. Si vous utilisez setState () pour un menu déroulant comme dans la réponse du haut de cet article, vous ne pouvez pas utiliser devtools pour déboguer les problèmes que vos utilisateurs pourraient rencontrer dans le menu déroulant. C'est pire lorsque vous utilisez setState () pour une superposition car il n'y a aucun moyen de voyager dans le temps avant et après l'affichage de la superposition. Arroser setState () ici et là est très sujet aux erreurs car le développeur doit constamment penser à ce qui pourrait casser.
kumar303 du

En guise de réponse plus spécifique, la journalisation de chaque variable dans une base de code n'est pas une métaphore utile puisque la question est de savoir s'il faut utiliser this.setState()ou dispatch(action...). Il n'est pas nécessaire de l'utiliser this.setState()partout, mais lorsque vous en avez besoin, ma suggestion est d'utiliser Redux à la place pour 99% des cas, en recourant au this.setState()1% en fonction des problèmes de performances.
kumar303 du

La journalisation de chaque variable me semble être analogue à tout mettre dans Redux et tout aussi déconseillée en règle générale. Laisser certaines choses en dehors de Redux n'annule pas les fonctionnalités de tout ce qui est dans Redux tant que l'état est séparé. C'est-à-dire que je peux toujours déboguer ma logique d'appel API qui est acheminée via Redux même si l'état d'une boîte de sélection ne l'est pas. L'OP a un point - il nécessite plus de code à plusieurs endroits pour utiliser Redux et cela n'est peut-être pas justifié dans l'exemple spécifique qu'ils ont répertorié.
JD Sandifer

Vous ne pourrez peut-être pas déboguer votre logique d'API, en fait. C'est mon point. Il est vraiment difficile de prévoir les scénarios dans lesquels vous interromprez le voyage dans le temps, il est donc préférable de mettre tout l'état (y compris l'état de la boîte de sélection) dans Redux jusqu'à ce qu'il y ait un problème de performances.
kumar303
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.