[英]React.js having state based on other state
我遇到了React.js的一些問題,並且在調用setState()時沒有立即設置狀態。 我不確定是否有更好的方法來解決這個問題,或者它是否真的只是React的一個缺點。 我有兩個狀態變量,其中一個是基於另一個。 (原始問題的小提琴: http : //jsfiddle.net/kb3gN/4415/你可以在日志中看到,當你點擊按鈕時它沒有立即設置)
setAlarmTime: function(time) {
this.setState({ alarmTime: time });
this.checkAlarm();
},
checkAlarm: function() {
this.setState({
alarmSet: this.state.alarmTime > 0 && this.state.elapsedTime < this.state.alarmTime
});
}, ...
當調用setAlarmTime
,因為this.state.alarmTime
並不會立即更新,給下面的調用checkAlarm
集alarmSet
基礎上的前值this.state.alarmTime
,因此是不正確。
我解決了這個通過移動電話來checkAlarm
到回調setState
在setAlarmTime
,但不必跟蹤的實際上是“正確”是什么狀態,並嘗試不完的事回調似乎可笑:
setAlarmTime: function(time) {
this.setState({ alarmTime: time }, this.checkAlarm);
}
有沒有更好的方法來解決這個問題? 在我的代碼中有一些其他地方我引用我剛設置的狀態,現在我不確定何時能夠真正信任狀態!
謝謝
是的, setState是異步的,因此this.state
不會立即更新。 以下是批處理的單元測試 ,可以解釋一些細節。
在上面的示例中, alarmSet
是根據alarmTime
和elapsedTime
狀態計算的數據。 一般而言,計算數據不應存儲在對象的狀態中,而應根據需要計算,作為渲染方法的一部分。 有一節什么不該進入州? 在交互性和動態用戶界面文檔的底部,它提供了這樣的事情的例子,它們不應該進入狀態,以及什么組件應該有狀態? 部分解釋了為什么這可能是一個好主意的一些原因。
正如Douglas所說,在this.state
保持計算狀態通常不是一個好主意,而是每次在組件的render
函數中重新計算它,因為狀態將在那一點上更新。
但是這對我來說不起作用,因為我的組件實際上有自己的更新循環,需要檢查並可能在每次滴答時更新其狀態。 由於我們不能指望this.state
在每個tick都被更新,我創建了一個包含React.createClass
並添加它自己的內部狀態跟蹤的解決方法。 (需要jQuery for $ .extend)(小提琴: http : //jsfiddle.net/kb3gN/4448/ )
var Utils = new function() {
this.createClass = function(object) {
return React.createClass(
$.extend(
object,
{
_state: object.getInitialState ? object.getInitialState() : {},
_setState: function(newState) {
$.extend(this._state, newState);
this.setState(newState);
}
}
)
);
}
}
對於您需要跟上時代的狀態呈現功能之外的任何部件,只需更換呼叫React.createClass
與Utils.createClass
。
您還可以改變所有this.setState
與調用this._setState
和this.state
與呼叫this._state
。
這樣做的最后一個結果是您將丟失組件中自動生成的displayName
屬性。 這是由於更換了jsx變壓器
var anotherComponent = React.createClass({
同
var anotherComponent = React.createClass({displayName: 'anotherComponent'
。
要解決這個問題,您只需手動將displayName屬性添加到對象中即可。
希望這可以幫助
不確定是否在詢問問題的情況下,盡管現在this.setState(stateChangeObject, callback)
的第二個參數this.setState(stateChangeObject, callback)
采用了可選的回調函數,所以可以這樣做:
setAlarmTime: function(time) {
this.setState({ alarmTime: time }, this.checkAlarm);
},
checkAlarm: function() {
this.setState({
alarmSet: this.state.alarmTime > 0 && this.state.elapsedTime < this.state.alarmTime
});
}, ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.