卸载后未清除React setTimeout或组件更新

时间:2019-03-29 13:41:24

标签: javascript reactjs typescript runtime-error

我有一个React.Component,出于动画目的,该states可以位于不同的内部State A -> setTimeout(goToStateB, 2000) -> State B中,使用超时来更改状态,例如:State A

您可以像在State B中看到动画那样,看到消息 Hello ,然后在2秒后,在Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.中看到按X开始< / em>。

问题是有时它会崩溃,并显示错误:React: 16.8.4。我使用setTimeout

我无法在本地重现问题,但是我确实跟踪错误,而且这种情况似乎经常发生。我知道这是setTimeout的问题,因为当我替换(在类似情况下,具有相同的错误)时,anime.js被替换为componentWillUnmount动画,而该动画在{{1 }}问题解决了。

该组件看起来像这样:

interface IState { finished: boolean; }

class TestComponent extends React.Component<{}, IState> {
    // constructor, other code, etc.

    private changeState(): void {
        this.setState({
            finished: true
        });

        // I also dispatch some other actions to the store, which might result in re-rendering of other components.
    }

    public componentDidMount(): void {
        this.changeState = this.changeState.bind(this); // This is also something really strange, if I bind in the constructor instead of in componentDidMount, the `this` value is different/wrong. So `this` in constructor is referring to a different element than `this` in comonentDidMount ??
        this.timeout = window.setTimeout(this.changeState, 2000);
    }

    public componentWillUnmount(): void {
        window.clearTimeout(this.timeout);
    }

    public render(): JSX.Element {
        return <div>
            {!this.state.finished ? 'Welcome!' : 'Press X to start.'}
        </div>;
    }
}

尽管超时应该在componentWillUnmount上清除,但看起来还是有些不对劲,或者清除得太迟了。

有什么主意如何解决该问题,或者如何进一步调试出什么问题以及为什么会发生特定的removeChild错误?

(不幸的是,这是)堆栈跟踪: NotFoundError
无法在“节点”上执行“ removeChild”:要删除的节点不是该节点的子节点。

enter image description here

有关触发错误的最终调用的更多详细信息。看起来React内部的某些事情会对超时/过期计时器做一些事情: enter image description here

0 个答案:

没有答案