J'étudie un cours React à un moment où l'instructeur explique comment mettre à jour les états et je ne comprends pas en quoi ces deux extraits sont vraiment différents en interne, veuillez consulter les liens codepen ci-dessous:
Met à jour directement l'extrait de code
updatedCounters[index] = {...counter};
Met à jour l'état indirectement puis enregistre l'extrait
class Counters extends Component {
state = {
counters: [
{ id: 1, value: 4 },
{ id: 2, value: 0 },
{ id: 3, value: 0 },
{ id: 4, value: 0 }
]
};
handleIncrement = counter => {
const updatedCounters = [...this.state.counters];
const index = updatedCounters.indexOf(counter);
updatedCounters[index] = {...counter};
updatedCounters[index].value++;
this.setState({ counters: updatedCounters });
};
}
Dans cette conférence , l'instructeur explique que le premier extrait de code met directement à jour l'état. Ma question est donc la suivante: si le premier exemple, comme le dit l'instructeur, met directement à jour l'état, la seule chose qui empêche le deuxième extrait de mettre directement à jour l'état est la ligne ci-dessous?:
class Counters extends Component {
state = {
counters: [
{ id: 1, value: 4 },
{ id: 2, value: 0 },
{ id: 3, value: 0 },
{ id: 4, value: 0 }
]
};
handleIncrement = counter => {
const updatedCounters = [...this.state.counters];
updatedCounters[0].value++;
};
}
3 Réponses :
Dans le premier exemple, updatedCounters est une copie de this.state.counters , mais les éléments à l'intérieur de cette copie sont des références au exactement les mêmes objets dans l'original. Cela pourrait être analogue à déplacer certains livres dans une nouvelle boîte. Le conteneur a changé, mais pas le contenu. Dans le deuxième exemple, vous ne modifiez pas le compteur sélectionné, vous copiez le compteur puis vous modifiez cette copie.
Merci Michelle
Sélection comme la bonne réponse car elle expliquait directement la question de la manière la plus simple
Fondamentalement, la réponse à ma propre question est que, si vous n'appelez pas setState react ne déclenchera pas les routines nécessaires pour mettre à jour la valeur "view" du composant à l'écran (en mentionnant le premier exemple)
Et si vous appelez setState , mais que vous faites muter l'ancien objet d'état, il finira par échouer car c'est un comportement non défini dans React et découragé.
Rappel, le seul moment où il est possible de définir l'état manuellement est chez le constructeur du composant
En ce qui concerne les modifications d'état dans React, vous devez toujours vous rappeler que l'état ne peut pas être muté. Eh bien, techniquement, vous pouvez le faire, mais c'est une mauvaise pratique et c'est un anti-modèle. Vous voulez toujours faire une copie de l'état et modifier la copie au lieu de l'objet d'état d'origine. Pourquoi ? Cela améliore vraiment les performances de l'application et c'est l'énorme avantage de React. Cela s'appelle immuabilité .
Vous pourriez également demander: "Comment cette approche améliore-t-elle les performances?"
Eh bien, en gros, grâce au modèle d'immuabilité, react n'a pas à vérifier l'intégralité de l'objet d'état. Au lieu de cela, React effectue une simple comparaison de références. Si l'ancien état ne fait pas référence au même obj. en mémoire -> nous savons que l'état a changé.
Essayez toujours d'utiliser .setState () pour éviter de muter l'état d'une mauvaise manière et c'est ce que vous faites ici:
handleIncrement = counter => {
const updatedCounters = [...this.state.counters];
updatedCounters[0].value++;
};
Gabriel Oliveira rend-il le sujet plus clair? :)
Pas de problème camarade :)
La différence est l'immuabilité.
De plus, la ligne est erronée, il est donc compréhensible que vous ayez du mal à la comprendre.
Copie possible de Quel est le meilleur moyen de mettre à jour un objet dans un tableau dans ReactJS?
Hey @EmileBergeron, alors vous dites que c'est juste parce que le premier extrait de code manque le this.setState? Quelle ligne ne va pas?
Alors @EmileBergeron, j'avais déjà vu ce post et je savais que je devais utiliser setState, je suppose que ma question aurait plus de sens si je pouvais montrer la vidéo que je regardais, mais je ne peux pas en raison des droits d'auteur. Mais, en visitant ce lien une fois de plus, j'ai lu toute la discussion et maintenant je comprends plus clairement certaines choses. Merci, il a aidé.
La ligne erronée est
udatedCounters [index] = [... counter];, vous l'avez corrigée dans l'extrait ci-dessus, mais pas dans le dernier extrait.