2017-09-28 24 views
1

所以在反應信任狀態,setState()是異步,並且可以緩衝調用改變狀態。我明白了。並且,如果您以某種方式依賴狀態來計算新狀態,可如何使用setState((state) => {})這樣的可選回調函數。我怎麼能在React.js

但可以說,我不想簡單地更新狀態,只是可以肯定的它實際上包含了在某個時間點?我們來舉個例子:

我有一個文本字段。當某人編輯該字段時,它將使用setState({ hasChanged: true })設置狀態。很好。在onClick回調(別的地方)我想檢查文本字段是否被「更改」並在繼續之前保存它的文本內容。但事情是我永遠不能確定state.hasChanged實際上是與現實同步。不像setState((state) => {})中的回調,我在這裏獨自一人。

所以做我創建了一個「影子狀態」(或者,至少是從反應狀態分離的狀態變量),並保持它的像這樣的情況下,剛剛更新了?似乎有點繁瑣,我懷疑這不是你應該怎麼做,所以這個問題。

編輯澄清:我只希望「檢查」狀態,並確保它的內容(因爲我我的情況,我會做一個保存到磁盤取決於它)。我其實不會更新狀態。如果是這樣的話,用的setState回調很可能是正確的選擇..

+0

我在這種情況下,我會像'previousStateTextFiled狀態添加屬性'並與當前比較。如果不是 - > currentState是前面提到的) –

回答

0

這是一個相當理論問題,這將最有可能永遠不會成爲方案的喜歡你給的例子有問題。

不管怎麼說,你可以傳遞一個回調對setState作爲第二個參數,它會被儘快你的狀態已經改變調用。

+0

是的,我想這是有點理論上的問題,但我現在正在設計一個反應應用程序,並且在將文本字段內容保存到磁盤之前(如果它已更改),然後用新內容填充它。這是我想成爲真正的原因*我確定我不會錯過保存它,因爲狀態與現實不同步。所以我想我可以使用setState與回調作爲柺杖(即使我實際上沒有更新狀態,而不是僅僅因爲它執行一個動作(保存到磁盤) – PKSWE

0

這就是爲什麼陣營有一個生命週期中,你可以通過聽的方法,如componentWillUpdatecomponentDidUpdate等(可以查看完整列表here)。 按照你的榜樣,當文本字段的變化,國家value被更新,你可以在「攔截」的方法componentWillUpdatecomponentDidUpdate這樣在此次調整:

class Main extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    
 
    this.state = { 
 
     value: '' 
 
    }; 
 

 
    this._handleOnChange = this._handleOnChange.bind(this); 
 
    } 
 
    
 
    
 
    componentWillUpdate(nextProps, nextState) { 
 
    if(nextState.value !== this.state.value) { 
 
     console.log('value will update'); 
 
    } 
 
    } 
 
    
 
    
 
    componentDidUpdate(prevProps, prevState) { 
 
    if(prevState.value !== this.state.value) { 
 
     console.log('value did update', this.state.value); 
 
    } 
 
    } 
 

 
    render() { 
 
    return (
 
     <form> 
 
     <input type='text' autoFocus onChange={this._handleOnChange} ref='text'/> 
 
     </form> 
 
    ); 
 
    } 
 
    
 
    _handleOnChange() { 
 
    this.setState({ 
 
     value: this.refs.text.value 
 
    }); 
 
    } 
 
} 
 

 

 
ReactDOM.render(<Main />, document.getElementById("main"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="main"></div>

你可以找到有關official docs中的狀態和生命週期的更多信息。

+0

'componentWillUpdate'是否也會延遲運行(批處理更改並在運行之前運行*只是*在渲染之前)或剛剛在狀態改變之後運行? – PKSWE

+0

它運行在'shouldComponentUpdate'之後。 ://busypeoples.github.io/post/react-component-lifecycle/ – juliobetta

+0

雖然我真的很欣賞這種努力,但是我沒有看到如何解決我的困境,也許我只是不理解你。我的問題是架構性的,我剛剛嘗試過'shouldComponentUpdate',它確實進行了批量更改,所以我可能會錯過特定的時間點,當我需要檢查並處理特定的狀態時,如果我取決於一些**決賽**狀態,那麼是的,它可能是某種解決方案。也許我可以引入狀態變量,我可以信任**最終**表單並對其執行操作。在任何情況下,感謝您的洞察力和想法 – PKSWE

0

我真的認爲這是一個非常困難的情況發生。我們知道setState只需要幾秒的時間來執行,而在真實的情況下,當點擊按鈕時,狀態已經改變。

爲了能夠充分信任react正在做一個好工作,我能想到的一些想法:

  • 您可以禁用按鈕時this.state.hasChanged是假的。因此,您應該始終等待下一個render檢查hasChanged的狀態並啓用它。

  • 使用內部state一個新的密鑰,說lastActioncomponentDidUpdate幫助有規則,如:

    if (this.state.lastAction === "myLastAction")

+0

這確實不太可能發生在這種情況下。然而,它*是一個特例,可能是一個很難追蹤的bug。除此之外(也許我在這裏挑剔)我想從一開始就「正確地做」,而不是依靠「它將在1000次中工作999次」。並感謝提示! – PKSWE