Получение ошибки React: setState(): можно обновить только смонтированный или смонтированный компонент ТОЛЬКО с дочерним компонентом

Целый день гоняюсь за этим багом. У меня есть очень простая точка входа в React и очень простой пример изменения состояния компонента. Если я поставлю компонент в точку входа, вот так:

import React from 'react';
import { render } from 'react-dom';

export default class Template extends React.Component {
  constructor(props) {
    super(props);

    this.toggleNavbar = this.toggleNavbar.bind(this);
    this.state = {
      collapsed: true,
    };
  }

  toggleNavbar() {
    this.setState({
      collapsed: !this.state.collapsed,
    });
  }
  render() {
    return (
      <div>
        <p>Collapsed: { this.state.collapsed ? 'true' : 'false' }</p>
        <button onClick={this.toggleNavbar}>Toggle</button>
      </div>
    );
  }
}

render(
  <Template />,
  document.querySelector('#react-app'),
);

Он работает так, как ожидалось. Вы нажимаете кнопку переключения, и текст меняется между «истина» и «ложь». Однако в ту минуту, когда я разбиваю его на два отдельных файла, я получаю это в качестве точки входа:

import React from 'react';
import { render } from 'react-dom';

import Template from './components/Template';

render(
  <Template />,
  document.querySelector('#react-app'),
);

и это для Template.jsx

import React from 'react';

export default class Template extends React.Component {
  constructor(props) {
    super(props);

    this.toggleNavbar = this.toggleNavbar.bind(this);
    this.state = {
      collapsed: true,
    };
  }

  toggleNavbar() {
    this.setState({
      collapsed: !this.state.collapsed,
    });
  }
  render() {
    return (
      <div>
        <p>Collapsed: { this.state.collapsed ? 'true' : 'false' }</p>
        <button onClick={this.toggleNavbar}>Toggle</button>
      </div>
    );
  }
}

Каждый раз, когда я нажимаю на кнопку, я получаю следующую ошибку в консоли:

build.js:23484 Предупреждение: setState(...): Можно обновить только смонтированный или смонтированный компонент. Обычно это означает, что вы вызвали setState() для несмонтированного компонента. Это не-операция. Проверьте код компонента "Шаблон".

... Я проверил все другие ответы переполнения стека на предмет этой ошибки (а также обыскал тонну), и ни один из них, похоже, здесь не применим. Кто-нибудь знает, что я делаю неправильно?

примечание: я пытался добавить:

componentWillUnmount() {
  this.isUnmounted = true;
}

и проверка !this.isUnmounted перед setState(), и я все еще получаю сообщение об ошибке.

Спасибо!


person Christopher Buecheler    schedule 03.07.2017    source источник
comment
Я попытался разобрать «создать-реагировать-приложение» до голых костей и запустить ваш код в созданном приложении, и это просто работает для меня. Это заставляет меня думать, что это, скорее всего, проблема, возникающая в результате сборки/комплектации. Мой репозиторий github для вашей проблемы: github.com/finbarrobrien/react-setstate   -  person Finbarr O'B    schedule 04.07.2017
comment
попробуй это onClick={() => {this.toggleNavbar()}} . Также добавьте расширение файла jsx в оператор импорта import Template from './components/Template.jsx';   -  person Fawaz    schedule 04.07.2017
comment
@FinbarrO'B - спасибо. Да, проблема с комплектацией. Я обнаружил проблему после того, как создал новое приложение с нуля (как и вы) и все настроил. Оказывается, у меня была ошибочная строка в моем .babelrc: "plugins": ["react-hot-loader/babel"] Я думаю, что произошло то, что каким-то образом конфликтовало с горячей перезагрузкой моего веб-пакета. В любом случае, его удаление решило проблему.   -  person Christopher Buecheler    schedule 04.07.2017


Ответы (1)


Я нашел проблему: мой .babelrc содержал эту строку:

  "plugins": ["react-hot-loader/babel"]

И это конфликтовало с остальной частью моей настройки горячей перезагрузки веб-пакета. Удаление этой строки помогло. Я думаю, что происходило то, что компонент отображался, но каким-то образом реакция запуталась в том, что было/не было смонтировано (возможно, он очень быстро монтировался, размонтировался, а затем снова монтировался, и поэтому связанная функция toggleClick пытался установить состояние старой версии компонента? Не уверен).

В любом случае, мораль этой истории такова: с кодом React все в порядке. Это была проблема с моей конфигурацией.

person Christopher Buecheler    schedule 04.07.2017