Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React.js具有基于其他状态的状态_Javascript_Reactjs - Fatal编程技术网

Javascript React.js具有基于其他状态的状态

Javascript React.js具有基于其他状态的状态,javascript,reactjs,Javascript,Reactjs,我在React.js中遇到了一些问题,调用setState()时没有立即设置状态。我不确定是否有更好的方法来解决这个问题,或者这是否真的只是React的一个缺点。我有两个状态变量,其中一个基于另一个。(原始问题的处理:您可以在日志中看到,当您单击按钮时,它没有立即设置) 有没有更好的办法?在我的代码中还有一些其他地方我引用了我刚刚设置的状态,现在我不确定何时我可以真正信任该状态 谢谢是的,它是异步的,因此不会立即更新此状态。下面是批处理的示例,可以解释一些细节 在上面的示例中,alarmSet是

我在React.js中遇到了一些问题,调用setState()时没有立即设置状态。我不确定是否有更好的方法来解决这个问题,或者这是否真的只是React的一个缺点。我有两个状态变量,其中一个基于另一个。(原始问题的处理:您可以在日志中看到,当您单击按钮时,它没有立即设置)

有没有更好的办法?在我的代码中还有一些其他地方我引用了我刚刚设置的状态,现在我不确定何时我可以真正信任该状态

谢谢

是的,它是异步的,因此不会立即更新此状态。下面是批处理的示例,可以解释一些细节


在上面的示例中,
alarmSet
是根据
alarmTime
elapsedTime
状态计算的数据。一般来说,计算数据不应存储在对象的状态中,而应根据需要作为渲染方法的一部分进行计算。在交互和动态UI文档的底部有一个部分,它给出了这样一些不应该进入状态的示例,并且该部分解释了为什么这可能是一个好主意的一些原因。

正如Douglas所说,将计算状态保持在
这个状态通常不是一个好主意,而是每次在组件的
render
函数中重新计算它,因为该点将更新状态

然而,这对我来说不起作用,因为我的组件实际上有它自己的更新循环,它需要在每次滴答声时检查并可能更新它的状态。由于我们不能指望
this.state
在每次勾选时都会被更新,因此我创建了一个变通方法,它包装了
React.createClass
,并添加了它自己的内部状态跟踪。(需要jQuery查询$.extend)(Fiddle:)

对于在渲染函数之外需要最新状态的任何组件,只需将对
React.createClass
的调用替换为
Utils.createClass

您还必须用
this.\u setState
更改所有
this.setState
调用和
this.state
调用
this.\u state

这样做的最后一个后果是,您将丢失组件中自动生成的
displayName
属性。这是由于更换了jsx变压器

var anotherComponent=React.createClass({

var anotherComponent=React.createClass({displayName:'anotherComponent'

要解决这个问题,您只需手动将displayName属性添加到对象中


希望这有助于

不确定提问时是否出现这种情况,尽管现在
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
  });
}, ...
setAlarmTime:函数(时间){
this.setState({alarmTime:time},this.checkAlarm);
},
checkAlarm:function(){
这是我的国家({
alarmSet:this.state.alarmTime>0&&this.state.elapsedTime
在大多数情况下,让状态尽可能小并在渲染函数中重新计算是有意义的,因为
这个状态将完全是最新的。但是,我认为这在我的情况下不起作用,因为这个组件实际上有自己的更新循环(使用setInterval)它必须在每次滴答声时更新并检查其状态。因此不能保证
render
会在滴答声之间运行。作为一种解决方法,我在
React.createClass
上实现了一个包装器,跟踪它自己的状态。我也会在这里添加它作为答案。这里有一篇关于RectJS流量体系结构的好文章:他们所做的一件事就是把“复杂的”视图层中React组件的状态,也可以应用于此处。与其将setInterval放在视图中,这可能是存储中发生的事情,然后每当存储更新时,它将触发视图重新渲染。存储可以是纯JS对象,而不具有setState的异步行为。感谢解释想知道如果我们可以将依赖状态移动到useEffect是否是一个好主意,那么种子状态的更改将触发其他所有内容的更新。我的问题是:计算数据不应存储在对象的状态中!一种更简单的方法是将您的状态完全存储在react之外,并将其传递给reactt作为道具-那么你的状态总是最新的,反应可能还没有协调好,这无关紧要。你不应该在
this.setState(…)
中使用
this.setState(…)
。因为
this.setState(…)
是异步的(大多数时候)您无法预测执行时
this.state
的内容。
this.setState(prevState=>({alarmSet:prevState.alarmTime>0&&prevState.elapsedTime
将是正确的方法。
setAlarmTime: function(time) {
  this.setState({ alarmTime: time }, this.checkAlarm);
}
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);
          }
        }
      )
    );
  }
}
setAlarmTime: function(time) {
  this.setState({ alarmTime: time }, this.checkAlarm);
},
checkAlarm: function() {
  this.setState({
    alarmSet: this.state.alarmTime > 0 && this.state.elapsedTime < this.state.alarmTime
  });
}, ...