Maison > Article > interface Web > À quoi devez-vous faire attention lorsque vous utilisez React.setState ?
Cet article présente principalement trois points auxquels il faut prêter attention lors de l'utilisation de React.setState. Il met en avant trois points faciles à ignorer pour les novices de React. Il a une certaine valeur de référence. Les amis intéressés peuvent s'y référer. >
Avant-propos
Le titre original de cet article est 3 raisons pour lesquelles j'ai arrêté d'utiliser React.setState , mais je ne suis pas très intéressé par les arguments avancés par l'auteur original, mais les trois points soulevés par l'auteur sont faciles à ignorer pour les novices de React, je ne mentionnerai donc qu'une partie du contenu ici et changerai le titre en trois points auxquels il faut prêter attention lors de l'utilisation de React.setState.Texte
Pour les novices de React, utiliser setState est une chose très compliquée. Même si vous êtes un développeur React expérimenté, il est très probable que certains bugs surviennent en raison de certains mécanismes de React, comme l'exemple suivant : Le document explique également lors de l'utilisation de setState Lorsque vous faites cela, à quoi devez-vous faire attention :Remarque :
Ne modifiez jamais this.state directement, car appeler setState() plus tard peut remplacer le modifications que vous avez apportéesChangement. Traitez cet état comme immuable. setState() ne modifie pas this.state immédiatement, mais crée une transition d'état qui sera bientôt traitée. Accéder à this.state après avoir appelé cette méthode peut renvoyer la valeur existante. Les appels à setState n'ont aucune garantie de synchronisation et les appels peuvent être regroupés pour des gains de performances. setState() déclenchera toujours un redessin à moins que la logique de rendu conditionnel ne soit implémentée dans ShouldComponentUpdate(). Si des objets mutables sont utilisés et que cette logique ne peut pas être implémentée dans ShouldComponentUpdate(), appeler setState() uniquement lorsqu'il existe une différence entre le nouvel état et l'état précédent peut éviter un nouveau rendu inutile. Pour résumer, lors de l'utilisation de setState, il y a trois problèmes auxquels il faut prêter attention :1. setState est asynchrone (Note du traducteur : la synchronisation n'est pas garantie)
De nombreux développeurs n'ont pas remarqué que setState est asynchrone au début. Si vous modifiez un état et que vous le visualisez ensuite directement, vous verrez l'état précédent. C'est l'endroit le plus sujet aux erreurs dans setState. Le mot setState n'a pas l'air asynchrone, il peut donc provoquer des bugs si vous l'utilisez sans réfléchir. L'exemple suivant illustre bien ce problème :class Select extends React.Component { constructor(props, context) { super(props, context) this.state = { selection: props.values[0] }; } render() { return ( <ul onKeyDown={this.onKeyDown} tabIndex={0}> {this.props.values.map(value => <li className={value === this.state.selection ? 'selected' : ''} key={value} onClick={() => this.onSelect(value)} > {value} </li> )} </ul> ) } onSelect(value) { this.setState({ selection: value }) this.fireOnSelect() } onKeyDown = (e) => { const {values} = this.props const idx = values.indexOf(this.state.selection) if (e.keyCode === 38 && idx > 0) { /* up */ this.setState({ selection: values[idx - 1] }) } else if (e.keyCode === 40 && idx < values.length -1) { /* down */ this.setState({ selection: values[idx + 1] }) } this.fireOnSelect() } fireOnSelect() { if (typeof this.props.onSelect === "function") this.props.onSelect(this.state.selection) /* not what you expected..*/ } } ReactDOM.render( <Select values={["State.", "Should.", "Be.", "Synchronous."]} onSelect={value => console.log(value)} />, document.getElementById("app") )À première vue, il ne semble y avoir aucun problème avec ce code. La méthode onSelect est appelée dans les deux gestionnaires d'événements. Cependant, il y a un bug dans ce composant Select qui illustre bien le GIF précédent. La méthode onSelect transmet toujours la valeur state.selection précédente, car lorsque fireOnSelect est appelé, setState n'a pas terminé son travail. Je pense que React devrait au moins changer setState en planningState ou faire de la fonction de rappel un paramètre obligatoire. Ce bug est facile à corriger. Le plus difficile est que vous devez savoir qu'il existe ce problème.
2. setState entraînera un rendu inutile
Le deuxième problème causé par setState est le suivant : chaque appel entraînera un nouveau rendu. Souvent, ces nouveaux rendus sont inutiles. Vous pouvez utiliser printWasted dans les outils de performances React pour voir quand un rendu inutile se produit. Cependant, grosso modo, il existe plusieurs raisons de rendu inutile :3.setState ne peut pas gérer efficacement tous les états des composants
Sur la base du dernier point ci-dessus, tous les états des composants ne sont pas SetState doit être utilisé pour enregistrer et mettre à jour. Les composants complexes peuvent avoir divers états qui doivent être gérés. L'utilisation de setState pour gérer ces états entraînera non seulement de nombreux rendus inutiles, mais entraînera également l'appel constant des hooks de cycle de vie associés, provoquant de nombreux problèmes étranges.Postface
Dans l'article original, l'auteur recommandait une bibliothèque appelée MobX pour gérer certains états. Je n'ai pas très froid, je ne la présenterai donc pas. Si vous êtes intéressé, vous pouvez lire l'introduction dans l'article original via le lien en haut. Sur la base des trois points soulevés ci-dessus, je pense que les débutants devraient prêter attention aux points suivants : setState n'est pas garanti d'être synchronisé setState n'est pas garanti d'être synchronisé , ce n'est pas garanti. La synchronisation n'est pas garantie. Dites les choses importantes trois fois. La raison pour laquelle il n'est pas dit asynchrone est que setState est également mis à jour de manière synchrone dans certains cas. Vous pouvez vous référer à cet articleSi vous avez besoin d'obtenir la valeur modifiée directement après setState, il existe plusieurs options : Passez les paramètres correspondants et ne l'obtenez pas via this.state针对于之前的例子,完全可以在调用 fireOnSelect 的时候,传入需要的值。而不是在方法中在通过 this.state 来获取
使用回调函数
setState 方法接收一个 function 作为回调函数。这个回掉函数会在 setState 完成以后直接调用,这样就可以获取最新的 state 。对于之前的例子,就可以这样:
this.setState({ selection: value }, this.fireOnSelect)
使用setTimeout
在 setState 使用 setTimeout 来让 setState 先完成以后再执行里面内容。这样子:
this.setState({ selection: value }); setTimeout(this.fireOnSelect, 0);
直接输出,回调函数, setTimeout 对比
componentDidMount(){ this.setState({val: this.state.val + 1}, ()=>{ console.log("In callback " + this.state.val); }); console.log("Direct call " + this.state.val); setTimeout(()=>{ console.log("begin of setTimeout" + this.state.val); this.setState({val: this.state.val + 1}, ()=>{ console.log("setTimeout setState callback " + this.state.val); }); setTimeout(()=>{ console.log("setTimeout of settimeout " + this.state.val); }, 0); console.log("end of setTimeout " + this.state.val); }, 0); }
如果val默认为0, 输入的结果是:
Direct call 0
In callback 1
begin of setTimeout 1
setTimeout setState callback 2
end of setTimeout 2
setTimeout of settimeout 2
和渲染无关的状态尽量不要放在 state 中来管理
通常 state 中只来管理和渲染有关的状态 ,从而保证 setState 改变的状态都是和渲染有关的状态。这样子就可以避免不必要的重复渲染。其他和渲染无关的状态,可以直接以属性的形式保存在组件中,在需要的时候调用和改变,不会造成渲染。
避免不必要的修改,当 state 的值没有发生改变的时候,尽量不要使用 setState 。虽然 shouldComponentUpdate 和 PureComponent 可以避免不必要的重复渲染,但是还是增加了一层 shallowEqual 的调用,造成多余的浪费。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!