【问题标题】:Set state in lifecycle method React JS在生命周期方法 React JS 中设置状态
【发布时间】:2018-06-30 21:30:58
【问题描述】:

我的 React 生命周期方法如下:

componentWillReceiveProps(nextProps){
    if(this.props.totalVehicles !== nextProps.totalVehicles){
        this.setState({animation: "cartCount"}, () => setTimeout(() =>  this.setState({animation: null}), 1000));
    }
}

但这给了我:

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the Header component.

如何在生命周期方法中设置状态而不出现这些错误?

【问题讨论】:

  • 理想情况下,您可以在componentWillReceiveProps 中设置状态,错误可能是因为您使用的是setTimeout。挂载完成后是设置状态,所以报错。
  • 您是否在执行 setTimeout 之前以某种方式离开组件,您可能会尝试使用此解决方案 stackoverflow.com/questions/39767482/… 并仅在组件已安装时在 setTimeout 中使用 setState
  • @ShubhamKhatri 不。
  • 否则您的代码似乎是正确的,我尝试对其进行演示,并且效果很好codesandbox.io/s/ymmp7vxw61

标签: reactjs


【解决方案1】:

将其设置为componentWillUpdate 怎么样?这样,您就知道该组件已经安装了。文档here

如果要设置初始状态,请在componentWillMount 中进行。

更多生命周期方法在here

【讨论】:

【解决方案2】:

您需要检查您的组件现在是否已安装。您可以在您的状态中创建触发器mounted 并在生命周期方法中对其进行管理。

constructor(props) {
 super(props);
 this.state = { mounted: false };
}

componentDidMount() {
 this.setState({ mounted: true });
}

componentWillUnmount() {
 this.setState({ mounted: false });
}

componentWillReceiveProps(nextProps){
 if(this.props.totalVehicles !== nextProps.totalVehicles && 
  this.state.mounted){
   this.setState({animation: "cartCount"}, () => setTimeout(() =>
    this.setState({animation: null}), 1000));
 }
}

【讨论】:

    【解决方案3】:

    虽然这是一个老问题,但我会回答它以供将来参考。

    当通过setTimeout 使用setState(异步)时,您必须记住清除componentWillUnmount 上的超时。 否则,您可能会遇到在元素已卸载后调用 setState 的情况。

    【讨论】:

      【解决方案4】:

      尝试使用实例变量“mounted”,而不是使用状态“mounted”:

      constructor(props) {
       super(props);
       this.mounted = false;
      }
      
      componentDidMount() {
       this.mounted = true;
      }
      
      componentWillUnmount() {
       this.mounted = false;
      }
      
      componentWillReceiveProps(nextProps){
       if(this.props.totalVehicles !== nextProps.totalVehicles && 
        this.mounted){
         this.setState({animation: "cartCount"}, () => setTimeout(() =>
          this.setState({animation: null}), 1000));
       }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多