React js延迟渲染会导致错误

时间:2017-12-01 17:10:34

标签: reactjs

我有一个表格,我应该在一段时间内渲染一个元素。我在setTimeout中使用componentDidMount来实现此目标,但我收到警告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 undefined component.

class Form extends React.Component {
    constructor(props, context) {
        this.state = {resend: false};
    }

    componentDidMount() {
        const max = 3;

        if (this.props.count < max) {
            setTimeout(() => {
                this.setState({resend: true});
            }, 1000);
        }
    }

    render() {
        return (
            <form>
                ...
                {this.state.resend ? <Component/> : null}
            </form>
        );
    }
}

2 个答案:

答案 0 :(得分:2)

您的组件可能在某个时候卸载,然后超时结束,并且在组件不再呈现后尝试调用setState。

您需要取消已在componentWillUnmount中运行的所有超时。存储对它们的引用并删除它们。

class Form extends React.Component {
    constructor(props, context) {
        this.state = {resend: false};
        this.timeouts = [];
    }

    componentWillUnmount(props, context) {
        this.timeouts.forEach(t => window.clearTimeout(t));
    }

    componentDidMount() {
        const max = 3;

        if (this.props.count < max) {
            const timeoutId = setTimeout(() => {
                this.setState({resend: true});
            }, 1000);
            this.timeouts.push(timeoutId);
        }
    }

    render() {
        return (
            <form>
                ...
                {this.state.resend ? <Component/> : null}
            </form>
        );
    }
}

答案 1 :(得分:0)

这可能是因为setTimeout调用时组件不存在。使用挂载标志来查看组件是否仍然存在。

constructor(props, context) {
  this.state = {resend: false};
  this.mounted = true;
}

componentWillUnmount() {
  this.mounted = false;
}

componentDidMount() {
  const max = 3;

  if (this.props.count < max) {
    setTimeout(() => {
      if (!this.mounted) return;
      this.setState({resend: true});
    }, 1000);
  }
}