javascript - 正确卸载 react 组件

标签 javascript reactjs ecmascript-6

抱歉,我无法为这个问题想出更具体的标题。当我执行下面的代码片段时,我收到以下警告:

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 Typewriter component.

但是,如果 MyComponent 中的 render() 更改为以下内容,我不会收到此类警告:

render() {
  return (
    <div>
      <h1>
        <Typewriter />
        { this.state.render == 1 && "Render 1" }
        { this.state.render == 2 && "Render 2" }
        { this.state.render == 3 && "Render 3" }
      </h1>
    </div>
  );
}

如何正确卸载这个渲染的打字机组件,该组件本身正在执行一些安装和卸载操作?谢谢!

class Typewriter extends React.Component {
  constructor(props) {
    super();
    this.state = {
      finalText: ''
    }
    this.typeWriter = this.typeWriter.bind(this);
  }

  typeWriter(text, n) {
    if (n < (text.length)) {
      if (n + 1 == (text.length)) {
        let j = text.substring(0, n+1);
        this.setState({ finalText: j });
        n++;
      }
      else {
        let k = text.substring(0, n+1) + '|';
        this.setState({ finalText: k });
        n++;
      }
      setTimeout( () => { this.typeWriter(text, n) }, 100 );
    }
  }

  componentDidMount() {
    this.typeWriter('testing_typewriter', 0);
  }

  render() {
    return (
      <div>
        { this.state.finalText }
      </div>
    );
  }
}

class MyComponent extends React.Component {
  constructor(props) {
    super();
    this.state = {
      render: 1,
      update: false
    };
    this.interval = null;
  }

  componentDidMount() {
    this.interval = setTimeout( () =>
      this.rendering(), 1700
    );
  }

  componentWillUpdate(nextProps, nextState) {
    if (this.state.render < 3) {
      this.interval = setTimeout( () =>
        this.rendering(), 1200
      );
    }
  }

  componentWillUnmount() {
      clearInterval(this.interval);
      this.interval = null;
  }

  rendering() {
    if (this.state.render < 3) {
      if (this.interval) {
        this.setState({ render: this.state.render + 1 });
      }
    }
  }

  render() {
    return (
      <div>
        <h1>
          { this.state.render == 1 && "Render 1" }
          { this.state.render == 2 && <Typewriter /> }
          { this.state.render == 3 && "Render 3" }
        </h1>
      </div>
    );
  }
}



ReactDOM.render(<MyComponent />, app);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="app"></div>

最佳答案

我遇到了类似的问题,我通过清除 componentWillUnmount 函数中的超时/间隔来解决它

在打字机功能中,您需要跟踪此超时:

setTimeout( () => { this.typeWriter(text, n) }, 100 );

类似的东西

this._timer = setTimeout( () => { this.typeWriter(text, n) }, 100 );

然后添加生命周期方法:

componentWillUnmount() {
  window.clearTimeout(this._timer);
}

关于javascript - 正确卸载 react 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46720506/

相关文章:

javascript - c# asp.net mvc - 使用参数从 html.actionlink 调用脚本函数

javascript - Web 应用程序无法在 Chrome 操作系统中的 Chromium 上运行

reactjs - React 和 Tailwind CSS 中的 SVG — 填充 : "currentColor" not working

javascript - 相同路由隐藏组件问题

javascript - 页面未重定向到更新的 URL

javascript - 使用 Rollup.js 导出函数列表 - ECMA6 模块

javascript - CouchdB Jquery Ajax POST CORS

javascript - React hooks 的使用效果

javascript - 如何在 javascript/react 中从另一个文件导入数据

javascript - 从 React 数组中填充选择选项