Javascript 从setState()更新视图时,未按预期触发重新渲染器

Javascript 从setState()更新视图时,未按预期触发重新渲染器,javascript,react-jsx,Javascript,React Jsx,回答: 我是个笨蛋。这已经太晚了,但我不想留下一条未回答的线索,尤其是因为我最初的回答是错误的。我需要参考我得到的新道具,而不是这个。道具。和往常一样,答案是在电话里。我在下面更新了我自己的答案以反映这一点 编辑1: 我的第一把小提琴没有完全显示我的问题,所以我必须更好地演示。出于某种原因,当我调用我的setState()时,我认为第一次通过它时是未定义的,即使它给定了一个值,但在随后的过程中它仍按预期工作。我的初始setState()调用似乎没有触发重新加载程序,但其他所有调用都会触发 与通常

回答: 我是个笨蛋。这已经太晚了,但我不想留下一条未回答的线索,尤其是因为我最初的回答是错误的。我需要参考我得到的新道具,而不是这个。道具。和往常一样,答案是在电话里。我在下面更新了我自己的答案以反映这一点

编辑1: 我的第一把小提琴没有完全显示我的问题,所以我必须更好地演示。出于某种原因,当我调用我的setState()时,我认为第一次通过它时是未定义的,即使它给定了一个值,但在随后的过程中它仍按预期工作。我的初始setState()调用似乎没有触发重新加载程序,但其他所有调用都会触发

与通常的“setState不更新视图”问题有点不同,因为setState()正在更新我的视图并使用正确的值。只是不是在我期望的时候。基本上,我正在触发一个setState()事件,该事件应使用新的道具重新启动我的子组件,我相信这将触发childs components components components WillReceiveProps lifecyle事件,该事件将在子组件内调用setState()并更新其视图。问题是,虽然它确实更新了视图,但它似乎比预期晚了一个周期。在我的MVP中,我在2秒时调用setState(),但它在4秒时更新视图。但我还不能确定哪一部分是错误的逻辑

这是我的名片。谢谢你的建议

代码:

类TaskBody扩展了React.Component{
建造师(道具){
超级(道具);
this.state={};
}
组件将接收道具(){
这是我的国家({
activeTask:this.props.activeTask
});
}
render(){
返回

{ this.state.activeTask?this.state.activeTask:“任务标题” }

; } } 类主体扩展了React.Component{ 建造师(道具){ 超级(道具); 此.state={ 活动任务:“”, 柜台:1 }; this.updateActive=this.updateActive.bind(this); } 更新活动(任务){ 这是我的国家({ 活动任务:任务 }); } componentDidMount(){ var self=这个; setInterval(函数(){ if(self.state.counter==4){ clearInterval(self.clickInterval); 返回clearInterval(self.countInterval); } self.setState({counter:self.state.counter+1}); }, 1000); //假设这是一个点击事件,它应该重新渲染视图 //因为我调用了setState(),所以在2秒的时间内瞬间完成,对吗? //它应该触发重新渲染,然后TaskBody应该 //接收新的道具,触发其在activeTask上设置状态(), //哪个应该更新视图? self.clickInterval=setInterval(函数(){ setState({activeTask:'花费了它应该花费的两倍时间'); }, 2000); } render(){ 返回 {this.state.counter} ; } } ReactDOM.render(,document.querySelector('#body');

实际上从来没有打过电话

原因如下:

您的逻辑位于
componentDidMount
生命周期方法中。如果你阅读,你会发现它清楚地说明:

仅在客户端(而不是服务器)上调用一次,然后立即调用 在初始渲染发生后

因此,当在应用程序中调用
componentDidMount
时,您首先要检查计数器并在那里调用
setState
。这将触发新的渲染。这意味着
componentDidMount
中的第二个代码块将无效,因为当您设置方法时,它永远不会被调用

实际上从来没有打过电话

原因如下:

您的逻辑位于
componentDidMount
生命周期方法中。如果你阅读,你会发现它清楚地说明:

仅在客户端(而不是服务器)上调用一次,然后立即调用 在初始渲染发生后


因此,当在应用程序中调用
componentDidMount
时,您首先要检查计数器并在那里调用
setState
。这将触发新的渲染。这意味着
componentDidMount
中的第二个代码块将不会有任何效果,因为当您设置方法时,它永远不会被调用到任何地方。

在我以前的回答中,我使用setTimeout()作为一种手段来获得我想要的结果。基本上,如果我在超时中包装我的setState,它将使用新的道具设置状态,但如果我不这样做,它仍将引用旧的道具。幸运的是,这已经在react中处理,因为componentWillReceiveProps默认情况下已经接收到一个newProps参数

这:

变成

componentWillReceiveProps(newProps){
      var self = this;
      self.setState({activeTask: newProps.activeTask});
}

在我以前的回答中,我使用setTimeout()作为一种手段来获得我想要的结果。基本上,如果我在超时中包装我的setState,它将使用新的道具设置状态,但如果我不这样做,它仍将引用旧的道具。幸运的是,这已经在react中处理,因为componentWillReceiveProps默认情况下已经接收到一个newProps参数

这:

变成

componentWillReceiveProps(newProps){
      var self = this;
      self.setState({activeTask: newProps.activeTask});
}

这篇来自Facebook的关于componentWillReceiveProps的帖子似乎是相关的:这篇来自Facebook的关于componentWillReceiveProps的帖子似乎是相关的:啊,你的权利。我认为我的例子没有正确地描述我的场景。我已经更新了我的小提琴,以便更好地反映这个问题。调用my setState()是因为它多次导致重新加载,但由于某些原因,它错过了第一次。或者我是个哑巴……啊,你说得对。我认为我的例子没有正确地描述我的场景。我已经更新了我的小提琴,以便更好地反映这个问题。调用my setState()是因为它多次导致重新加载,但由于某些原因,它错过了第一次。或者也许我很笨。。。
componentWillReceiveProps(){
      var self = this;
      setTimeout(function(){
        self.setState({activeTask: self.props.activeTask});
      },0);
}
componentWillReceiveProps(newProps){
      var self = this;
      self.setState({activeTask: newProps.activeTask});
}