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

Какая разница this.state и this.setstate в ReactJS?

Я хочу изменить значение для клавиши hasSubmit, как в разделе "Первый код". Я знаю, что это не рекомендуется. Но второй код является асинхронным, и я не хочу использовать функцию обратного вызова setState.

  • В чем разница this.state и setState?
  • Можно ли сразу изменить значение состояния hasSubmit?

Первый код: this.state.hasSubmit = false this.setState({}) //Code that will use `hasSubmit`.

Второй код: this.setState({ hasSubmit: false, }); //Code that will use `hasSubmit`.


ADD:

Сценарий таков:

  • hasSubmit установлен false в getInitialState().
  • hasSubmit изменится на false, когда я нажму кнопку submit.
  • hasSubmit при отправке будет изменен на true.

Первый щелчок submit не имеет проблем и hasSubmit будет установлен true.

Но второй щелчок submit будет ошибочным, используя Second asynchronous code, потому что hasSubmit по-прежнему true, а First Code может решить проблему.

4b9b3361

Ответ 1

Вот что React docs говорит:

НИКОГДА не мутируйте this.state напрямую, так как вызов setState() впоследствии может заменить мутацию, которую вы сделали. Относитесь к this.state как к неизменному.

setState() не сразу мутирует this.state, но создает ожидающий переход состояния. Доступ к this.state после вызова этого метода может потенциально вернуть существующее значение.

Нет гарантии синхронной работы вызовов setState, и вызовы могут быть собраны для повышения производительности. setState() всегда будет вызывать повторную визуализацию, если логика условного воспроизведения не реализована в shouldComponentUpdate().

Если используются изменяемые объекты и логика не может быть реализована в shouldComponentUpdate(), вызов setState() только тогда, когда новое состояние отличается от предыдущего состояния, избежит ненужных повторных рендеров.

Всегда разумно использовать API-интерфейсы так, как они были разработаны. Если документы говорят, что они не мутируют ваше состояние, тогда вам лучше не мутировать ваше состояние.

Хотя setState() может быть технически асинхронным, он, конечно, не замедляется каким-либо заметным образом. Функция компонента render() вызывается в довольно коротком порядке.

Один из недостатков настройки состояния заключается в том, что методы жизненного цикла React - shouldComponentUpdate(), componentWillUpdate(), componentDidUpdate() - зависят от переходов состояний, вызываемых с помощью setState(). Если вы измените состояние напрямую и вызовите setState() с пустым объектом, вы больше не сможете реализовать эти методы.

Другим является то, что это просто плохой стиль программирования. Вы делаете в двух утверждениях, что вы могли бы сделать в одном.

Кроме того, здесь нет реальной выгоды. В обоих случаях render() не запускается, пока не вызывается setState() (или forceUpdate()).

Вы утверждаете, что вам нужно сделать это, не объясняя, что это необходимо. Возможно, вы хотели бы подробнее рассказать о своей проблеме. Возможно, лучшее решение.

Лучше всего работать с каркасом, а не против него.

UPDATE

Из комментариев ниже:

Потребность в том, что я хочу использовать измененный hasSubmit ниже.

Хорошо, теперь я понимаю. Если вам нужно немедленно использовать свойство будущего состояния, лучше всего хранить его в локальной переменной.

const hasSubmit = false;

this.setState({
  hasSubmit: hasSubmit
});

if (hasSubmit) { 
  // Code that will use `hasSubmit` ...

Ответ 2

Вы никогда не должны игнорировать рекомендации по документации. На момент написания статьи setState разрешает второй аргумент, который является функцией обратного вызова, когда завершались setState и re-render. Поскольку вы никогда не предоставляете нам, как ваш код будет использовать значение hasSubmit, я считаю, что некоторые другие могут найти это полезным, когда они захотят убедиться, что hasSubmit был изменен.

Ответ 3

Вы должны использовать this.forceUpdate() в первом примере, чтобы принудительно обновить состояние. Например:

this.state.hasSubmit = false;
this.forceUpdate();

Но лучше использовать this.setState, потому что это init native check-state mecanizm из React engine, который лучше, чем принудительное обновление.

Если вы просто обновите любой параметр this.state напрямую без setState, отредактируйте рендер mecanizm не будет знать, что обновлены некоторые параметры состояния.

Ответ 4

this.setState поддерживает жизненный цикл реагирующего компонента и не кажется мутирующим переменным (хотя внутренне он мутирует состояние). Таким образом, односторонний поток в реакционном цикле поддерживается без каких-либо побочных эффектов.

Предостережение с использованием this.setState не работает с конструкторами классов ES6. Нам нужно использовать шаблон this.state = вместо this.setState в конструкторах ES6

Ответ 5

Если вы хотите изменить состояние и вызвать повторную визуализацию, отредактируйте:

Использовать второй код BTW: этот код не использует обратный вызов setState:

  this.setState({
    hasSubmit: false,
  });

Проблемы/ошибки с первым кодом:

  this.state.hasSubmit = false      // Updates state directly: 
                                    // You are not supposed to do this
                                    // except in ES6 constructors
  this.setState({})                 // passes an empty state to react.
                                    // Triggers re-render without mutating state

Если вы хотите изменить состояние без запуска повторной обработки: Поместите второй код внутри componentWillReceiveProps, как описано здесь в официальных документах реагирования.