Heim >Web-Frontend >js-Tutorial >Was sollten Sie bei der Verwendung von React.setState beachten?
In diesem Artikel werden hauptsächlich drei Punkte vorgestellt, die bei der Verwendung von React.setState beachtet werden müssen. Es werden drei Punkte genannt, die für React-Neulinge leicht zu ignorieren sind. Es hat einen gewissen Referenzwert >
Vorwort
Der Originaltitel dieses Artikels lautet 3 Gründe, warum ich React.setState nicht mehr verwendet habe, aber die Argumente des ursprünglichen Autors interessieren mich nicht sehr. Aber die drei vom Autor angesprochenen Punkte sind für React-Neulinge leicht zu ignorieren, daher werde ich hier nur einen Teil des Inhalts erwähnen und den Titel in drei Punkte ändern, die bei der Verwendung von React.setState beachtet werden müssen.Text
Für React-Neulinge ist die Verwendung von setState eine sehr komplizierte Sache. Selbst wenn Sie ein erfahrener React-Entwickler sind, ist es sehr wahrscheinlich, dass aufgrund einiger Mechanismen von React einige Fehler auftreten, wie zum Beispiel das folgende Beispiel: Das Dokument erklärt auch bei der Verwendung von setState Was sollten Sie dabei beachten:Hinweis:
Ändern Sie this.state niemals direkt, da ein späterer Aufruf von setState() das ersetzen kann Änderungen, die Sie vorgenommen habenÄnderung. Behandeln Sie this.state als unveränderlich. setState() ändert this.state nicht sofort, sondern erstellt einen Zustandsübergang, der bald verarbeitet wird. Der Zugriff auf this.state nach dem Aufruf dieser Methode gibt möglicherweise den vorhandenen Wert zurück. Aufrufe an setState haben keine Synchronisierungsgarantien und Aufrufe können zur Leistungssteigerung gestapelt werden. setState() löst immer eine Neuzeichnung aus, es sei denn, die bedingte Rendering-Logik ist in ShouldComponentUpdate() implementiert. Wenn veränderliche Objekte verwendet werden und diese Logik nicht in ShouldComponentUpdate() implementiert werden kann, kann der Aufruf von setState() nur dann, wenn ein Unterschied zwischen dem neuen Zustand und dem vorherigen Zustand besteht, unnötiges erneutes Rendern vermeiden. Zusammenfassend lässt sich sagen, dass bei der Verwendung von setState drei Probleme zu beachten sind:1. setState ist asynchron (Anmerkung des Übersetzers: Synchronisierung ist nicht garantiert)
Vielen Entwicklern ist zunächst nicht aufgefallen, dass setState asynchron ist. Wenn Sie einen Status ändern und ihn dann direkt anzeigen, wird der vorherige Status angezeigt. Dies ist die fehleranfälligste Stelle in setState. Das Wort setState sieht nicht asynchron aus und kann daher Fehler verursachen, wenn Sie es unüberlegt verwenden. Das folgende Beispiel veranschaulicht dieses Problem gut: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") )Auf den ersten Blick scheint an diesem Code nichts auszusetzen zu sein. Die Methode onSelect wird in beiden Event-Handlern aufgerufen. Es gibt jedoch einen Fehler in dieser Select-Komponente, der das vorherige GIF gut darstellt. Die onSelect-Methode übergibt immer den vorherigen state.selection-Wert, da setState beim Aufruf von fireOnSelect seine Arbeit noch nicht abgeschlossen hat. Ich denke, React sollte zumindest setState in ScheduleState ändern oder die Callback-Funktion zu einem erforderlichen Parameter machen. Dieser Fehler ist leicht zu beheben. Das Schwierigste ist, dass Sie wissen müssen, dass es dieses Problem gibt.
2. setState führt zu unnötigem Rendering
Das zweite durch setState verursachte Problem ist: Jeder Aufruf führt zu einem erneuten Rendering. Oft sind diese erneuten Renderings unnötig. Sie können printWasted in den React-Leistungstools verwenden, um zu sehen, wann unnötiges Rendering auftritt. Grob gesagt gibt es jedoch mehrere Gründe für unnötiges Rendern:3.setState kann nicht alle Komponentenzustände effektiv verwalten
Basierend auf dem letzten Punkt oben sollten nicht alle Komponentenzustände mit SetState verwendet werden speichern und aktualisieren. Komplexe Komponenten können unterschiedliche Zustände aufweisen, die verwaltet werden müssen. Die Verwendung von setState zum Verwalten dieser Zustände führt nicht nur zu vielen unnötigen erneuten Renderings, sondern führt auch dazu, dass zugehörige Lebenszyklus-Hooks ständig aufgerufen werden, was zu vielen seltsamen Problemen führt.Nachwort
Im Originalartikel empfahl der Autor eine Bibliothek namens MobX, um einige Zustände zu verwalten, deshalb werde ich sie nicht vorstellen. Wenn Sie interessiert sind, können Sie die Einleitung im Originalartikel über den Link oben lesen. Basierend auf den drei oben genannten Punkten denke ich, dass Neulinge Folgendes beachten sollten: setState ist nicht garantiert synchronisiert. setState ist nicht garantiert synchronisiert , es ist nicht garantiert. Die Synchronisierung ist nicht garantiert. Sagen Sie wichtige Dinge dreimal. Der Grund, warum es nicht als asynchron bezeichnet wird, liegt darin, dass setState in einigen Fällen auch synchron aktualisiert wird. Sie können auf diesen Artikel verweisenWenn Sie den geänderten Wert direkt nach setState abrufen müssen, gibt es mehrere Möglichkeiten: Übergeben Sie die entsprechenden Parameter und erhalten Sie ihn nicht über 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 的调用,造成多余的浪费。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
Das obige ist der detaillierte Inhalt vonWas sollten Sie bei der Verwendung von React.setState beachten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!