Il me manque probablement quelque chose de très évident et j'aimerais me dégager.
Voici ma compréhension.
Dans une composante de réaction naïve, nous avons states
& props
. La mise à jour de state
avec setState
rend à nouveau le composant entier. props
sont la plupart du temps en lecture seule et leur mise à jour n’a aucun sens.
Dans un composant de réaction qui est abonné à un magasin redux, via quelque chose comme store.subscribe(render)
, il restitue évidemment le rendu à chaque fois que le magasin est mis à jour.
react-redux a un assistant connect()
qui injecte une partie de l’arbre d’état (qui présente un intérêt pour le composant) et actionCreators sous la forme props
du composant, généralement via
const TodoListComponent = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
Cependant, étant entendu que la valeur setState
est essentielle pour que TodoListComponent
réagisse au changement d'arborescence d'état redux (retransformation), je ne trouve aucun code associé à state
ou setState
dans le fichier de composant TodoList
. Il se lit comme ceci:
const TodoList = ({ todos, onTodoClick }) => (
<ul>
{todos.map(todo =>
<Todo
key={todo.id}
{...todo}
onClick={() => onTodoClick(todo.id)}
/>
)}
</ul>
)
Quelqu'un peut-il me diriger dans la bonne direction quant à ce qui me manque?
P.S Je suis l'exemple de liste de tâches fourni avec le paquetage redux ( https://github.com/reactjs/redux/tree/master/examples/todos/src/containers ).
La fonction connect
génère un composant wrapper qui s'abonne au magasin. Lorsqu'une action est distribuée, le rappel du composant encapsuleur est notifié. Il exécute ensuite votre fonction mapState
et shallow-compare le résultat obtenu à partir de cette heure contre le résultat précédent (si vous deviez réécrirecela ne déclencherait pas un re-rendu). Si les résultats sont différents, les résultats sont alors transmis à votre "véritable" composant "en tant qu'accessoires.
Dan Abramov a écrit une excellente version simplifiée de connect
à https://Gist.github.com/gaearon/1d19088790e70ac32ea636c025ba424e qui illustre l’idée de base, bien qu’elle ne montre aucun travail d’optimisation. J'ai également des liens vers un certain nombre d'articles sur Redux performance qui traitent de certaines idées connexes.
mettre à jour
React-Redux v6.0.0 a apporté des modifications internes majeures à la manière dont les composants connectés reçoivent leurs données du magasin.
Dans le cadre de ce travail, j’ai écrit un article qui explique le fonctionnement de l’API connect
et de ses internes, ainsi que leur évolution au fil du temps:
Redux idiomatique: historique et implémentation de React-Redux
Ma réponse est un peu en dehors du champ gauche. Cela met en lumière un problème qui m'a amené à ce poste. Dans mon cas, il me semblait que l'application n'était pas un nouveau rendu, même si elle recevait de nouveaux accessoires.
React devs avait une réponse à cette question souvent posée: si le (magasin) était muté, 99% du temps, c’est la raison pour laquelle réagit ne restitue pas le rendu. 1%. La mutation n'était pas le cas ici.
TLDR;
componentWillReceiveProps
indique comment lastate
peut être synchronisée avec la nouvelleprops
.
Cas Edge: Une fois state
mises à jour, alors l'application fait re-rendre!
Il s'avère que si votre application utilise uniquement state
pour afficher ses éléments, props
peut se mettre à jour, mais state
ne le fera pas, ainsi aucun rendu ne sera rendu.
J'avais state
qui dépendait de props
reçu de redux store
. Les données dont j'avais besoin n'étaient pas encore dans le magasin, alors je les ai extraites de componentDidMount
, comme il convient. J'ai récupéré les accessoires lorsque mon réducteur a mis à jour son magasin, car mon composant est connecté via mapStateToProps. Mais la page n'a pas rendu, et l'état était toujours plein de chaînes vides.
Un exemple de ceci est qu'un utilisateur a chargé une page "modifier le message" à partir d'une URL sauvegardée. Vous avez accès à la variable postId
à partir de l'URL, mais les informations ne sont pas encore dans la variable store
. Vous devez donc les récupérer. Les éléments de votre page sont des composants contrôlés. Ainsi, toutes les données que vous affichez sont dans state
.
À l'aide de redux, les données ont été extraites, le magasin a été mis à jour et le composant est connect
ed, mais l'application n'a pas reflété les modifications. À y regarder de plus près, props
ont été reçus, mais l'application n'a pas été mise à jour. state
n'a pas été mis à jour.
props
se mettra à jour et se propagera, mais state
ne le fera pas . Vous devez spécifiquement indiquer à state
de se mettre à jour.
Vous ne pouvez pas faire cela dans render()
, et componentDidMount
est déjà terminé ses cycles.
componentWillReceiveProps
est l'endroit où vous mettez à jour les propriétés state
qui dépendent d'une valeur prop
modifiée.
Exemple d'utilisation:
componentWillReceiveProps(nextProps){
if (this.props.post.category !== nextProps.post.category){
this.setState({
title: nextProps.post.title,
body: nextProps.post.body,
category: nextProps.post.category,
})
}
}
Je me dois de citer cet article qui m'a éclairé sur la solution que des dizaines d'autres publications, blogs et pensions n'ont pas mentionné. Toute autre personne qui a eu du mal à trouver une réponse à ce problème évidemment obscur, la voici:
Méthodes du cycle de vie des composants ReactJs - Une plongée profonde
componentWillReceiveProps
est l'endroit où vous mettrez à jourstate
pour rester synchronisé avec les mises à jourprops
.Une fois que
state
est mis à jour, alors champs en fonction destate
do re-rendre!
comme je sais que la seule chose que redux fait, lors du changement d'état du magasin, on appelle composantWillRecieveProps si votre composant dépend de l'état muté et que vous devez obliger votre composant à mettre à jour
1 appel d'état de changement de magasin-2 (composantWillRecieveProps (() => {changement d'état de 3 composants})))