setState(…):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState()。这是无人值守

reactjs React.js

GO神奇

2020-03-13

componentDidMount(prevProps, prevState, prevContext) {
    let [audioNode, songLen] = [this.refs.audio, List.length-1];

    audioNode.addEventListener('ended', () => {
        this._endedPlay(songLen, () => {
            this._currSong(this.state.songIndex);
            this._Play(audioNode);
        });
    });

    audioNode.addEventListener('timeupdate', () => {
        let [remainTime, remainTimeMin, remainTimeSec, remainTimeInfo] = [];

        if(!isNaN(audioNode.duration)) {
            remainTime = audioNode.duration - audioNode.currentTime;
            remainTimeMin = parseInt(remainTime/60);  // 剩余分
            remainTimeSec = parseInt(remainTime%60);  // 剩余秒

            if(remainTimeSec < 10) {
                remainTimeSec = '0'+remainTimeSec;
            }
            remainTimeInfo = remainTimeMin + ':' + remainTimeSec;
            this.setState({'time': remainTimeInfo});
        }
    });
}

componentWillUnmount () {
    let audio = this.refs.audio;
    audio.removeEventListener('timeupdate');
    audio.removeEventListener('ended');
}

错误:

警告:setState(...):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState()。这是无人值守。请检查未定义组件的代码。

我在中删除了EventListener'ended' componentWillUnmount,但是它不起作用。因为我添加this.setState({'time': remainTimeInfo});componentDidMount

第1531篇《setState(…):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState()。这是无人值守》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

6个回答
宝儿Sam 2020.03.13

addEventListener和removeEventListener,回调不得为Anonymous内部类,并且它们应具有相同的参数

蛋蛋樱 2020.03.13
  1. 取消中的所有异步操作 componentWillUnmount
  2. 由于不赞成使用isMounted标志setState,因此在异步调用时检查组件已经卸载。
LEY米亚 2020.03.13

我想在Ajax请求的成功/失败回调中显示一个弹出窗口(引导模式)时,收到此警告。另外,setState无法正常工作,并且我的弹出模式没有显示。

以下是我的情况-

<Component /> (Containing my Ajax function)
    <ChildComponent />
        <GrandChildComponent /> (Containing my PopupModal, onSuccess callback)

我从孙组件中调用组件的ajax函数,并传递了onSuccess回调(在孙组件中定义),该回调将状态设置为显示弹出模式。

我将其更改为-

<Component /> (Containing my Ajax function, PopupModal)
    <ChildComponent />
        <GrandChildComponent /> 

相反,我调用setState(onSuccess回调)在组件(ajax回调)本身中显示弹出模式,并解决了问题。

在第二种情况下:组件被渲染两次(我在HTML中两次包含bundle.js)。

Tom阳光达蒙 2020.03.13

我遇到此问题是因为我在构造函数中使用setState而不是state

更改以下错误代码

constructor(props) {
  super(props);
  this.setState({
    key: ''
  });
}

constructor(props) {
  super(props);
  this.state = {
    key: ''
  }; 
}
小宇宙前端 2020.03.13

我通过为组件分配ref解决此问题,然后在设置状态之前检查ref是否存在:

myMethod(){
  if (this.refs.myRef) 
   this.setState({myVar: true});
}

render() {
  return (
    <div ref="myRef">
      {this.state.myVar}
    </div>
  );
}
西里米亚 2020.03.13

自从我更新了最新的React版本以来,我遇到了同样的问题。解决如下。

我的代码是

async componentDidMount() {
  const { default: Component } = await importComponent();
  Nprogress.done();
  this.setState({
    component: <Component {...this.props} />
  });
}

变成

componentWillUnmount() {
  this.mounted = false;
}
async componentDidMount() {
  this.mounted = true;
  const { default: Component } = await importComponent();
  if (this.mounted) {
    this.setState({
      component: <Component {...this.props} />
    });
  }
}

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android