2015-06-11 56 views
160

我在閱讀文檔的Forms部分,並試圖使用此代碼來演示onChange的用法(JSBIN)。爲什麼調用react setState方法不會立即改變狀態?

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') 
); 

當我更新瀏覽器中的<input/>值,第二console.loghandleChange回調打印相同value爲第一console.log,爲什麼我不能看到handleChange回調的範圍this.setState({value: event.target.value})結果裏面?

回答

322

從陣營的documentation

setState()不會立即發生變異this.state但創建一個 掛起狀態轉變。調用此 方法後訪問this.state可能會返回現有值。沒有 保證setState的呼叫同步操作,並且可能調用 以獲得性能增益。

如果您希望在發生狀態更改後執行某個函數,請將其作爲回調函數傳遞。

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

很好的回答。我需要做的事情是小心使用valueLink。如果你不需要格式化/屏蔽輸入,它會很好用。 – Dherik

+2

完美。不知何故,我完全錯過了一個回調參數。 –

+15

您可能還想查看'componentDidUpdate'。它會在州改變後被調用。如果我可以 – Keysox

18

隨着陣營文檔中提到,沒有任何的setState保證被解僱同步,所以你可以console.log它更新之前,返回的狀態。

邁克爾帕克提到在setState內傳遞迴調。狀態更改後處理邏輯的另一種方法是通過componentDidUpdate生命週期方法,這是React文檔中推薦的方法。

通常我們推薦使用componentDidUpdate()代替這樣的邏輯。

當可能有連續的setState被解僱時,這是特別有用的,並且您希望在每次狀態更改後都觸發相同的功能。如果需要,可以將函數放置在componentDidUpdate的內部,而不是將回調添加到每個setState

// example 
componentDidUpdate(prevProps, prevState) { 
    if (this.state.value > prevState.value) { 
    this.foo(); 
    } 
} 
+0

應該接受答案。 – vikash

3

這裏的陣營文檔說:

從來沒有直接發生變異this.state,如調用的setState()之後可以更換 所做的突變。將this.state視爲不可變的。

setState()不會立即改變this.state,但會創建一個掛起狀態 轉換。調用此方法後訪問this.state可能會返回 現有值。

無法保證setState調用的同步操作,並且可能會調用 以提高性能。的setState()將總是觸發重新 渲染除非條件呈現邏輯在 shouldComponentUpdate()實現。

如果使用可變對象和所述邏輯不能在 shouldComponentUpdate()來實現,在調用的setState()僅當新的狀態從以前的狀態不同 將避免不必要的重新呈現。

+0

你可以在你的回答中添加一個鏈接到文檔嗎?謝謝。 – Pang

0

嘛,所以啞soloution,但也許它可以幫助別人誰是不熟悉的回退。在我的情況下,我用temp變量解決了這個問題。

我有用戶測試,我計算正確答案的問題,將它們保存到測試狀態的數量和最後一個問題回答後,我想立即顯示在狀態正確答案的數目。 但是,該州正在恢復舊的價值。所以我這樣做:

const numberOfCorrectQuestionsTemp = this.state.numberOfCorrectQuestions; 
if (questionCorrect) { 
    numberOfCorrectQuestionsTemp++; 
} 
this.setState({ 
    numberOfCorrectQuestions: numberOfCorrectQuestionsTemp, 
}); 
if (isLastQuestion) { 
    // display the result in percentage - with actual new value 
    alert((100/(this.state.numberOfQuestions)) * numberOfCorrectQuestionsTemp + '%'); 
} 

但更好的解決方案,在異步操作後執行某些操作是使用回調。你可以在這裏找到它:When to use React setState callback

相關問題