簡體   English   中英

React.js具有基於其他狀態的狀態

[英]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並不會立即更新,給下面的調用checkAlarmalarmSet基礎上的前值this.state.alarmTime ,因此是不正確。

我解決了這個通過移動電話來checkAlarm到回調setStatesetAlarmTime ,但不必跟蹤的實際上是“正確”是什么狀態,並嘗試不完的事回調似乎可笑:

setAlarmTime: function(time) {
  this.setState({ alarmTime: time }, this.checkAlarm);
}

有沒有更好的方法來解決這個問題? 在我的代碼中有一些其他地方我引用我剛設置的狀態,現在我不確定何時能夠真正信任狀態!

謝謝

是的, setState是異步的,因此this.state不會立即更新。 以下是批處理的單元測試 ,可以解釋一些細節。

在上面的示例中, alarmSet是根據alarmTimeelapsedTime狀態計算的數據。 一般而言,計算數據不應存儲在對象的狀態中,而應根據需要計算,作為渲染方法的一部分。 有一節什么不該進入州? 在交互性和動態用戶界面文檔的底部,它提供了這樣的事情的例子,它們不應該進入狀態,以及什么組件應該有狀態? 部分解釋了為什么這可能是一個好主意的一些原因。

正如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.createClassUtils.createClass

您還可以改變所有this.setState與調用this._setStatethis.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM