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

Cri*_*sty 5 javascript runtime-error typescript reactjs

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

您可以想到动画,就像State A您看到消息Hello,然后在2秒钟后State B看到按X开始

问题是有时它会崩溃,并显示错误:Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.。我用React: 16.8.4

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

该组件看起来像这样:

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>;
    }
}
Run Code Online (Sandbox Code Playgroud)

即使超时应该在上清除componentWillUnmount,它也总是不被清除,或者清除为时已晚。

是否知道如何解决此问题,或如何进一步调试出什么问题以及为什么removeChild会发生该特定错误?

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

在此处输入图片说明

有关触发错误的最终调用的更多详细信息。看起来React内部的某些事情会对超时/过期计时器做一些事情: 在此处输入图片说明