wake-up-neo.net

Warum ruft der Aufruf der reag setState-Methode den Status nicht sofort auf?

Ich lese gerade Forms Abschnitt der reactjs Dokumentation und habe gerade diesen Code ausprobiert, um die Verwendung von onChange ( JSBIN ) zu demonstrieren.

var React= require('react');

var ControlledForm= React.createClass({
    getInitialState: function() {
        return {
            value: "initial value"
        };
    },

    handleChange: function(event) {
        console.log(this.state.value);
        this.setState({value: event.target.value});
        console.log(this.state.value);

    },

    render: function() {
        return (
            <input type="text" value={this.state.value} onChange={this.handleChange}/>
        );
    }
});

React.render(
    <ControlledForm/>,
  document.getElementById('mount')
);

Wenn ich den <input/>-Wert im Browser aktualisiere, druckt der zweite console.log im handleChange-Callback das gleiche value wie der erste console.log. Warum kann ich das Ergebnis von this.setState({value: event.target.value}) nicht im handleChange-Callback sehen?

232
tarrsalah

Aus der Dokumentation von React :

setState() mutiert this.state nicht sofort, sondern erstellt eine anstehender Zustandsübergang. Zugriff auf this.state nach Aufruf von Methode kann möglicherweise den vorhandenen Wert zurückgeben. Es gibt kein Garantie für den synchronen Betrieb von Aufrufen von setState und Aufrufen können für Leistungsgewinne gestapelt werden.

Wenn Sie möchten, dass eine Funktion nach dem Statuswechsel ausgeführt wird, übergeben Sie sie als Rückruf.

this.setState({value: event.target.value}, function () {
    console.log(this.state.value);
});
484
Michael Parker

Wie in der React-Dokumentation erwähnt, gibt es keine Garantie dafür, dass setState synchron ausgelöst wird, sodass der console.log möglicherweise den Status vor der Aktualisierung zurückgibt.

Michael Parker erwähnt das Weiterleiten eines Rückrufs innerhalb der setState. Eine andere Möglichkeit, die Logik nach dem Zustandswechsel zu handhaben, ist die Lebenszyklusmethode componentDidUpdate, die in React-Dokumenten empfohlen wird.

Im Allgemeinen empfehlen wir, componentDidUpdate () stattdessen für eine solche Logik zu verwenden.

Dies ist besonders nützlich, wenn nacheinander setStates ausgelöst werden und Sie nach jeder Statusänderung dieselbe Funktion auslösen möchten. Anstatt jeder setState einen Rückruf hinzuzufügen, können Sie die Funktion innerhalb der componentDidUpdate platzieren, falls erforderlich mit einer bestimmten Logik.

// example
componentDidUpdate(prevProps, prevState) {
  if (this.state.value > prevState.value) {
    this.foo();  
  }
}
39
Yo Wakita

Sie können versuchen, ES7 async/await zu verwenden. Zum Beispiel anhand Ihres Beispiels:

handleChange: async function(event) {
    console.log(this.state.value);
    await this.setState({value: event.target.value});
    console.log(this.state.value);
}
5
black

Achten Sie auf die Lebenszyklusmethoden von React!

Ich habe mehrere Stunden gearbeitet, um herauszufinden, dass getDerivedStateFromProps nach jeder setState() aufgerufen wird. 

????

3
osrpt

Die async-await-Syntax funktioniert perfekt für Folgendes:.

changeStateFunction = () => {
  // Some Worker..

  this.setState((prevState) => ({
  year: funcHandleYear(),
  month: funcHandleMonth()
}));

goNextMonth = async () => {
  await this.changeStateFunction();
  const history = createBrowserHistory();
  history.Push(`/calendar?year=${this.state.year}&month=${this.state.month}`);
}

goPrevMonth = async () => {
  await this.changeStateFunction();
  const history = createBrowserHistory();
  history.Push(`/calendar?year=${this.state.year}&month=${this.state.month}`);
}
0
Ritwik

Einfach ausgedrückt: this.setState ({data: value}) ist asynchroner Natur, dh es wird aus dem Aufrufstapel verschoben und erst wieder in den Aufrufstapel zurückgeführt, wenn es nicht aufgelöst wird.

Bitte lesen Sie über Event Loop, um ein klares Bild über die asynchrone Natur in JS zu erhalten und warum das Aktualisieren einige Zeit in Anspruch nimmt.

https://medium.com/front-end-weekly/javascript-event-loop-explained-4cd26af121d4

Daher -

    this.setState({data:value});
    console.log(this.state.data); // will give undefined or unupdated value

da es Zeit braucht, um zu aktualisieren. Um den obigen Prozess zu erreichen -

    this.setState({data:value},function () {
     console.log(this.state.data);
    });
0
Vishal Bisht