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