Состояние в React - это концепция одна из наиболее трудных в изучении. Важно понимать не только то, что нужно хранить в состоянии, а также и что собственно состояние из себя представляет и для чего оно вообще нужно. А также как Redux связан с состоянием в React.
В этой статье, я надеюсь прояснить некоторые вещи.
Вы продолжаете использовать это слово...
Во-первых, слово "состояние" немного неоднозначно. В каком-то смысле "состояние" означает текущее, визуальное представление приложения на экране. Приложение может быть в состоянии "загрузки" или в состоянии "ошибки". Это не совсем то, что оно означает в React жаргоне.
В React, состояние - это объект, который представляет собой части приложения, которые могут изменяться. У каждого компонента может быть своё состояние, которое находится в свойстве объекта this.state.
Проще говоря, если вы хотите чтобы ваше приложение что-то делало, если вы хотите интерактивности, добавления и удаления каких-то элементов, авторизации пользователей, то потребуется состояние.
На что похоже состояние в React
Представьте, что у вас есть приложение, которое в текущий момент времени выглядит следующим образом:
Глядя на эту картинку можно выделить можно выделить части, которые с течением времени будут изменяться:
Теперь мы можем дать имена этим частям (время, использование мощности, температура в помещении, температура на улице), и описать их как простой JavaScript объект, например так:
{
currentTime: "2016-10-12T22:25:42.564Z",
power: {
min: 0,
current: 37,
max: 100
},
indoorTemperature: {
min: 0.0,
current: 72.0,
max: 100.0
},
outdoorTemperature: {
min: -10.0,
current: 84.0,
max: 120.0
},
tempUnits: "F"
}
Этот объект описывает всё состояние данного приложения. В двух словах, это React состояние.
Обратите внимание, что поля не полностью соответствуют UI. Это нормально. Отформатировать дату достаточно легко, а использование минимального и максимального позволит рисовать графики в правильных масштабах.
Суть в следующем: изменение состояния приложения приводит к изменению внешнего вида приложения.
Читатель foobarwtf указывает на то, что min и max не изменяются, а если они не изменяются почему они внутри state? Ну, потому что это распространённая практика, размещать ответы от сервера в состоянии. Если данные по текущей температуре, которые вы запрашиваете с сервера содержат min и max, лучше сохранить их в состоянии вместе с остальной частью. То что эти значения не изменятся, сейчас выглядит очевидным, но мне кажется что вы бы не хотели дублировать жёстко закодированные данные на сервере и на клиенте. Что случится если сервер изменит свою калибровку? Что если пользователь установит систему напряжения в 200A?
Итак, состояние как правило используется для "изменяемых" вещей, но это также хорошее место для хранения "изменчивых" данных, например тех, которые приходят с сервера.
Как изменять состояние
Если что-то измениться в состоянии... например температура внутри комнаты поднимется до 75°, приложение должно обновиться, чтобы сразу отобразить новую реальность. Это то, что делает React при изменении состояния: он повторно визуализирует приложение.
Вот некоторые причины, по которым состояние может изменяться:
- Пользователь кликает или нажимает на кнопки;
- Какие-то данные получены с сервера, или из веб-сокета, или из ответа на предыдущий запрос;
- Сработал таймер. Возможно есть таймер, который срабатывает каждую секунду, чтобы обновить текущее время на экране;
Итак, откуда React знает, что состояние изменилось? Всё время прослушивает все изменения? Следит за событиями, как это делает Angular? Нет. Никакой фантастики.
React знает, что состояние изменилось, потому что вы говорите ему об этом в явном виде, с помощью вызова функции this.setState внутри компонента. Другими словами, нет никакой "магии". React будет делать только то, что вы ему скажете.
Изменения состояния на примере счётчика
Приложение домашнего мониторинга, является хорошим примером состояния, но я собираюсь упростить его до элементарного счётчика, чтобы показать как состояние изменяется с течением времени.
Вот как это работает:
- Отображаемое число начинается с 0;
- Вы нажимаете на кнопку (это приводит к вызову функции handleClick, которую вы объявляете);
- Счётчик увеличивается на 1 (для этого вы вызываете функцию setState);
- React заново визуализирует приложение, в ответ на изменение состояния;
Покажите мне код
Быстрый обзор:
- React поддерживает состояние как объект;
- Вы можете изменять этот объект с помощью setState;
- React будет заново визуализировать приложение, каждый раз когда вы вызываете setState;
Ещё 2 важных момента:
- Вы не должны напрямую изменять this.state. Используйте this.setState;
- Изменения состояния - асинхронны. Если вы попытаетесь получить значение this.state сразу после вызова this.setState, вероятно он не будет содержать изменений.
Вот код для счётчика из компонента показанного выше:
Визуализация работы кода с отладчиком
DevTools отладчик неоценим при поиске ошибок, но это также отличный способ увидеть порядок выполнения кода. Расставьте точки остановки в ключевых местах и нажмите на кнопку Play (или обновите страницу). Вот как работает наше приложение счётчика:
Детали, детали
В этой статье я говорил, что состояние представляет собой один объект, который описывает всё приложение, но на практике оно разбивается на более мелкие куски. Лучший способ сделать это, хранить состояние в компонентах "контейнерах", а вывод хранить в "презентационных" контейнерах.
Если вы используете Redux, у вас на самом деле будет один большой объект состояния, который описывает всё приложение. Это основное, что делает Redux: один огромный объект, который представляет состояние приложения, а редьюсеры и mapStateToProps разрезают его на части, относящиеся к компонентам.
Я надеюсь, что помог прояснить для вас, что такое состояние. Оставляйте какие-либо вопросы и комментарии ниже.
Комментарии
Хорошая статья для первичного понимания! Спасибо!
Спасибо, хорошо объясняешь!