Подтвердить что ты не робот

SetState (...): Может обновлять только смонтированный или монтируемый компонент. Обычно это означает, что вы вызывали setState() на немонтированном компоненте. Это не-op

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() на unmounted компонент. Это не-op. Пожалуйста, проверьте код для undefinedкомпонент.

Я удаляюEventListener 'закончился' в componentWillUnmount, но он не работает. потому что я добавляю this.setState({'time': remainTimeInfo}); в componentDidMount.

4b9b3361

Ответ 1

Я решил это, назначив компоненту ref, а затем проверяя, существует ли ref перед установкой состояния:

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

render() {
  return (
    <div ref="myRef">
      {this.state.myVar}
    </div>
  );
}

Ответ 2

removeEventListener имеет ту же подпись, что и addEventListener. Все аргументы должны быть точно такими же, чтобы удалить слушателя.

var onEnded = () => {};
audioNode.addEventListener('ended', onEnded, false);

this.cleanup = () => {
  audioNode.removeEventListener('ended', onEnded, false);
}

И в вызове componentWillUnmount this.cleanup().

Ответ 3

Изменить: isMounted устарел и, вероятно, будет удален в более поздних версиях React. См. this, и это, isMounted является Антипаттерном.


Как указано в предупреждении, вы вызываете this.setState на компонент, который был установлен, но с тех пор был размонтирован.

Чтобы убедиться, что ваш код в безопасности, вы можете его обернуть в

if (this.isMounted()) {
    this.setState({'time': remainTimeInfo});
}

чтобы убедиться, что компонент все еще установлен.

Ответ 4

У меня была эта проблема раньше, и я решил ее в соответствии с React officail page isMounted является Антипаттерном.

Установите флаг isMounte свойства true в componentDidMount и установите его false в componentWillUnmount. Когда вы setState() в своих обратных вызовах, сначала проверьте isMount! Это работает для меня.

state = {
    isMounted: false
  }
  componentDidMount() {
      this.setState({isMounted: true})
  }
  componentWillUnmount(){
      this.setState({isMounted: false})
  }

Обратный вызов:

if (this.state.isMounted) {
 this.setState({'time': remainTimeInfo});}

Ответ 5

Многие ответы в этой теме дают смысл использовать ссылки, но я думаю, что полный пример будет хорошим. Поскольку вы работаете с фактическим DOM node, используя прослушиватель событий и выходя из контекста React, ref следует рассматривать как стандартное решение. Вот полный пример:

class someComponent extends Component {
  constructor(props) {
    super(props)
    this.node = null
  }
  render() {
    return (
      <div ref={node => { this.node = node }}>Content</div>
    )
  }
  handleEvent(event) {
    if (this.node) {
      this.setState({...})
    }
  }
  componentDidMount() {
    //as soon as render completes, the node will be registered.
    const handleEvent = this.handleEvent.bind(this)
    this.node.addEventListener('click', handleEvent)
  }
  componentWillUnmount() {
    const handleEvent = this.handleEvent.bind(this)
    this.node.removeEventListener('click', handleEvent)
  }
}

Ответ 6

addEventListener и removeEventListener, Callback не должен быть анонимным внутренним классом, и они должны иметь одинаковые параметры