Перевод "Using a function in `setState` instead of an object"
Документация React была обновлена—если вы еще не ознакомились с ней, то обязательно должны это сделать! Я немного помогаю с документацией в написании “Glossary of React Terms” (“Словарь терминов React”) и в процессе внимательно читаю всю новую документацию. В процессе чтения документации я узнала об относительно неизвестных сторонах “setState” и была вдохновлена этим твитом:
Seems more often, I want the behavior of React's setState((s,p) => s) API rather than setState(nextState) API. Former discourages staleness.
— jordanIsNotaFunction (@jordwalke) 30 декабря 2016 г.
Я решила написать статью в блоге, чтобы объяснить как это работает.
Компоненты в React являются независимыми и повторно используемыми кусками кода, который часто содержит свое собственное состояние. Они возвращают элементы React, из которых собирается интерфейс приложения. Компоненты, который содержат локальное состояние имеют свойство state
. Если вы хотите изменить данные в интерфейсе или поведение вашего приложения, то необходимо изменить состояние компонента. Итак, как вам обновить состояние нашего компонента? Компонент имеет доступный ему метод setState
. Вызов setState
позволяет React перестроить ваше приложение и обновить DOM.
Обычно когда необходимо обновить компонент вы просто вызываетеsetState
с новым значением переданным в виде объекта в функциюsetState
:
this.setState({someField:someValue})
Но часто необходимо обновить состояние компонента используя текущее состояние компонента. Непосредственный доступthis.state
для обновления компонента не является надежным методом. Выдержка из документации:
Так какthis.props
иthis.state
могут обновляться асинхронно, то не стоит полагаться на их значения для вычисления нового состояния.
Ключевое слово здесь—асинхронный. Обновление DOM не происходит мгновенно при вызове this.setState
. React поочередно обновляет элементы, чтобы максимально эффективно обновить DOM.
Рассмотрим типичный пример использования setState
. В Shopsifter есть форма обратной связи, в которой после отправки показывается сообщение с благодарностью:
Компонент для страницы обратной связи имеет параметр showForm
, который определяет когда показывать сообщение об успешной отправке на экране. Начальное состояние компонента такое:
this.state = { showForm : true}
Когда пользователь кликает на кнопку отправки вызывается функция:
submit(){
this.setState({showForm : !this.state.showForm});
}
Я использую значение для this.state.showForm
для изменения следующего состояния формы. В примере у вас не должно возникнуть вопросов по использованию значения, но вы можете представить как приложение становится более сложным и оно уже имеет множество данных в setState
, вызывающих изменение и выстраивающих данные в очередь для перерисовки DOM. В этом случае вы вероятно получите значение this.state.showForm
не то, которое ожидали.
“Вы продолжаете использовать “this.state”. Я не думаю, что это значит то, что вы думаете.”
Если не стоит опираться на this.state
для расчета нового состояния, то как вычислить новое значение?
'setState'
Вместо отправки объекта в this.setState
мы можем отправить функцию и надежно получить текущее значение компонента. Функция отправки из примера выше сейчас выглядит так:
submit(){
this.setState(function(prevState, props){
return {showForm: !prevState.showForm}
});
}
Отправка функции в setState
вместо объекта позволит получить вам достоверные значения для state
и props
компонента. Отмечу, что в документации React используются стрелочный функции в примерах (которые также есть в моем списке будущих изменений на Shopsifter), так я использую синтаксис ES5 в функции в примере выше.
Если вы знаете, что собираетесь использовать setState
для обновления вашего компонента и собираетесь использовать текущее значение state
или props
для вычисления новых значений, то отправляйте функцию в качестве первого параметра в this.setState
вместо объекта в качестве рекомендованного метода.
@tylermcginnis33 Not only not wrong, but it is also actively recommended if you're setting state based on previous state. pic.twitter.com/O7MXhj15j6
— Dan Abramov (@dan_abramov) 3 января 2017 г.
Надеюсь это поможет вам делать более надежные приложения в React.
-София