что такое state в react
Состояние state и события в React
Учебник по React
Учебник Angular 1.5.8
Сейчас мы с вами освоим работу с событиями в фреймворке React, а также подробнее поговорим о свойствах и методах объектов-компонентов.
State
Основным понятием React является state (состояние, стейт).
В state хранится текущее состояние компонента в виде объекта <> с ключами и значениями. Что входит в понятие текущее состояние?
Во-первых, это какие-либо данные. Например, компонент показывает на экране список имен юзеров. Эти имена изначально должны где-то хранится, обычно в каком-то массиве. Вот этот массив и должен хранится в state.
Работа со state
Давайте выведем данные из стейта при рендеринге, то есть в методе render():
Результатом работы этого кода будет следующее:
Таким образом, в конструкторе нашего класса мы можем записывать какие-то данные в стейт, а затем выводить их в других методах (чаще всего в методе render, но не обязательно), обращаясь к ним через this.state.имяСостояния.
Работа с событиями
Давайте теперь изучим работу с событиями на React. К примеру, сделаем так, чтобы по клику на блок выводился алерт с некоторым текстом.
Пусть у нас есть метод showMessage, который выводит алерт с сообщением, а в методе render у нас есть div, по клику на который нам и хотелось бы видеть этот алерт:
Давайте теперь привяжем к нашему диву событие onclick так, чтобы по клику на этот див срабатывал метод showMessage.
Для этого мы напишем следующее:
Теперь по клику на див будет выводиться сообщение:
Таким образом и происходит работа с событиями: добавляется атрибут (к примеру, onClick или onFocus), значением атрибута указывается метод, который будет вызван по этому событию.
Работа с this
Пусть теперь в конструкторе у нас задан this.state, в котором хранится имя и фамилия пользователя:
Давайте сделаем так, чтобы метод showMessage выводил имя нашего пользователя, хранящегося в стейте (то есть ‘Иван’). Кажется, что в методе showMessage следует поменять alert(‘Привет!’) на alert(this.state.name), но это не будет работать:
Теперь все будет работать, как надо:
Если вы запустите этот код и нажмете на div, то все будет работать так, как и работало: вы увидите алерт с сообщением ‘Иван’.
Вы можете пользоваться тем способом, который вам кажется более удобным.
Изменение стейта
Пусть в this.state хранится имя пользователя:
Давайте в методе render выведем его на экран:
Давайте теперь сделаем кнопку, по нажатию на которую будет меняться имя пользователя. Пусть по клику на эту кнопку вызывается метод changeName:
Обратите также внимание на .bind(this) в строчке onClick=
С помощью этого метода мы сможем поменять значение this.state.name, вот так: this.setState(
Почему именно так, а не напрямую: потому что в этом случае все места вставки вида сменят свое значение.
То есть: после вызова this.setState(
Давайте соберем все вместе:
Примечание
Если в стейте несколько значений, то в this.setState мы передаем только те, которые хотим поменять. Пример: пусть в стейте кроме имени хранится еще и фамилия, но мы по прежнему хотим менять только имя:
Если вы запустите этот код и нажмете на div, то все будет работать так, как и работало: ‘Иван’ мгновенно поменяется на ‘Коля’.
Но никто не мешает нам поменять несколько значений:
Что вам делать дальше:
Приступайте к решению задач по следующей ссылке: задачи к уроку.
Component State
What does setState do?
setState() schedules an update to a component’s state object. When state changes, the component responds by re-rendering.
props (short for “properties”) and state are both plain JavaScript objects. While both hold information that influences the output of render, they are different in one important way: props get passed to the component (similar to function parameters) whereas state is managed within the component (similar to variables declared within a function).
Here are some good resources for further reading on when to use props vs state :
Why is setState giving me the wrong value?
In React, both this.props and this.state represent the rendered values, i.e. what’s currently on the screen.
Example of code that will not behave as expected:
See below for how to fix this problem.
How do I update state with values that depend on the current state?
Pass a function instead of an object to setState to ensure the call always uses the most updated version of state (see below).
Passing an update function allows you to access the current state value inside the updater. Since setState calls are batched, this lets you chain updates and ensure they build on top of each other instead of conflicting:
When is setState asynchronous?
Currently, setState is asynchronous inside event handlers.
This ensures, for example, that if both Parent and Child call setState during a click event, Child isn’t re-rendered twice. Instead, React “flushes” the state updates at the end of the browser event. This results in significant performance improvements in larger apps.
This is an implementation detail so avoid relying on it directly. In the future versions, React will batch updates by default in more cases.
Why doesn’t React update this.state synchronously?
As explained in the previous section, React intentionally “waits” until all components call setState() in their event handlers before starting to re-render. This boosts performance by avoiding unnecessary re-renders.
However, you might still be wondering why React doesn’t just update this.state immediately without re-rendering.
There are two main reasons:
This GitHub comment dives deep into the specific examples.
Should I use a state management library like Redux or MobX?
It’s a good idea to get to know React first, before adding in additional libraries. You can build quite complex applications using only React.
State and Lifecycle
This page introduces the concept of state and lifecycle in a React component. You can find a detailed component API reference here.
Consider the ticking clock example from one of the previous sections. In Rendering Elements, we have only learned one way to update the UI. We call ReactDOM.render() to change the rendered output:
In this section, we will learn how to make the Clock component truly reusable and encapsulated. It will set up its own timer and update itself every second.
We can start by encapsulating how the clock looks:
Ideally we want to write this once and have the Clock update itself:
To implement this, we need to add “state” to the Clock component.
State is similar to props, but it is private and fully controlled by the component.
Converting a Function to a Class
You can convert a function component like Clock to a class in five steps:
Clock is now defined as a class rather than a function.
The render method will be called each time an update happens, but as long as we render into the same DOM node, only a single instance of the Clock class will be used. This lets us use additional features such as local state and lifecycle methods.
Adding Local State to a Class
We will move the date from props to state in three steps:
Note how we pass props to the base constructor:
We will later add the timer code back to the component itself.
The result looks like this:
Next, we’ll make the Clock set up its own timer and update itself every second.
Adding Lifecycle Methods to a Class
In applications with many components, it’s very important to free up resources taken by the components when they are destroyed.
We want to set up a timer whenever the Clock is rendered to the DOM for the first time. This is called “mounting” in React.
We also want to clear that timer whenever the DOM produced by the Clock is removed. This is called “unmounting” in React.
We can declare special methods on the component class to run some code when a component mounts and unmounts:
These methods are called “lifecycle methods”.
The componentDidMount() method runs after the component output has been rendered to the DOM. This is a good place to set up a timer:
Note how we save the timer ID right on this ( this.timerID ).
While this.props is set up by React itself and this.state has a special meaning, you are free to add additional fields to the class manually if you need to store something that doesn’t participate in the data flow (like a timer ID).
We will tear down the timer in the componentWillUnmount() lifecycle method:
Finally, we will implement a method called tick() that the Clock component will run every second.
It will use this.setState() to schedule updates to the component local state:
Now the clock ticks every second.
Let’s quickly recap what’s going on and the order in which the methods are called:
Using State Correctly
Do Not Modify State Directly
For example, this will not re-render a component:
Instead, use setState() :
The only place where you can assign this.state is the constructor.
State Updates May Be Asynchronous
React may batch multiple setState() calls into a single update for performance.
Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.
For example, this code may fail to update the counter:
To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
We used an arrow function above, but it also works with regular functions:
State Updates are Merged
For example, your state may contain several independent variables:
Then you can update them independently with separate setState() calls:
The Data Flows Down
Neither parent nor child components can know if a certain component is stateful or stateless, and they shouldn’t care whether it is defined as a function or a class.
This is why state is often called local or encapsulated. It is not accessible to any component other than the one that owns and sets it.
A component may choose to pass its state down as props to its child components:
The FormattedDate component would receive the date in its props and wouldn’t know whether it came from the Clock ’s state, from the Clock ’s props, or was typed by hand:
This is commonly called a “top-down” or “unidirectional” data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components “below” them in the tree.
If you imagine a component tree as a waterfall of props, each component’s state is like an additional water source that joins it at an arbitrary point but also flows down.
To show that all components are truly isolated, we can create an App component that renders three s:
Each Clock sets up its own timer and updates independently.
In React apps, whether a component is stateful or stateless is considered an implementation detail of the component that may change over time. You can use stateless components inside stateful components, and vice versa.
2.6 Состояние и жизненный цикл
В этом разделе мы расскажем о таких важных концепциях, как состояние и жизненный цикл компонента React. Более подробный API компонента вы можете найти здесь.
Рассмотрим, упомянутый ранее, пример тикающих часов.
Пока что мы знаем только один способ обновления UI.
В этом разделе мы сделаем компонент Timer по-настоящему переиспользуемым и инкапсулированным. Он сначала установит собственный таймер, а затем станет периодически обновляться через определенный промежуток времени.
Давайте начнём с инкапсуляции кода в компонент Timer :
В идеале, нам необходимо спроектировать самообновляющийся компонент Timer так, чтобы код, который его использует имел следующий вид:
Чтобы этого добиться, к компоненту Timer нужно добавить состояние.
Состояние похоже на свойства props, однако является приватным и полностью контролируется компонентом.
Раньше состоянием могли обладать только компоненты-классы. Однако с появлением хуков состоянием могут обладать и компоненты-функции.
2.6.1 Преобразование функций в классы
Мы можем преобразовать компонент-функцию Timer в класс за пять шагов:
Теперь компонент Timer определён как класс, а не как функция.
2.6.2 Добавление локального состояния в класс
Давайте переместим date из props в state в три этапа.
1. Заменим this.props.value на this.state.value в методе render() :
2. Добавим конструктор класса, который устанавливает начальное состояние this.state :
Обратите внимание на то, как мы передаем свойства props в базовый конструктор:
3. Удаляем свойство value из элемента:
Позже мы добавим код таймера обратно в сам компонент.
Результат будет выглядеть следующим образом:
Далее мы сделаем так, что компонент Timer будет устанавливать таймер и обновлять себя каждую секунду.
2.6.3 Добавление методов жизненного цикла в класс
При старте приложения React, компонент Timer будет впервые отрисован в DOM. В React это называется монтированием/монтажом компонента.
После каждого монтирования Timer ему нужно устанавливать таймер, чтобы периодически себя обновлять.
Однако в приложениях с множеством компонентов очень важно высвобождать ресурсы, занятые компонентами, когда они уничтожаются, чтобы избежать утечек памяти.
React позволяет объявить в компоненте-классе специальные методы, чтобы запускать определенный код, когда компонент монтируется или демонтируется:
В документации эти методы называются «lifecycle hooks». Мы же для простоты будем называть их методами жизненного цикла (ЖЦ).
Мы будем очищать таймер в методе жизненного цикла componentWillUnmount() :
Теперь компонент постоянно обновляется через установленный промежуток времени.
Давайте подытожим всё, что произошло, а также порядок, в котором вызываются методы:
Когда результат отрисовки Timer вставлен в DOM, React вызывает метод componentDidMount() жизненного цикла. Внутри него компонент Timer обращается к браузеру для установки таймера, чтобы вызывать increment() раз в секунду.
Если компонент Timer в какой-то момент удалён из DOM, React вызывает метод componentWillUnmount() жизненного цикла, из-за чего таймер останавливается.
2.6.4 Корректное обновление состояния
О setState() нужно знать три вещи.
2.6.4.1 Не модифицируйте состояние напрямую
К примеру, этот компонент перерисовываться не будет:
Для корректной модификации состояния компонента используйте метод setState() :
Вы можете установить this.state только в конструкторе!
2.6.4.2 Обновления состояния могут быть асинхронными
React может собирать последовательность вызовов setState() в единое обновление в целях повышения производительности.
Так как React может обновлять this.props и this.state асинхронно, вы не должны полагаться на их значения для вычисления следующего состояния.
К примеру, такой код может не обновить температуру:
Мы использовали стрелочную функцию, но можно использовать и обычные функции:
2.6.4.3 Обновления состояния объединяются
Например, состояние вашего компонента может содержать множество независимых переменных:
Далее вы можете обновить их независимо с помощью отдельных вызовов setState() :
2.6.5 Нисходящий поток данных
Вот почему состояние часто называют локальным или инкапсулированным. Оно недоступно для какого-либо компонента, за исключением того, который им владеет и устанавливает.
Компонент может решить передать это состояние вниз как свойства props своим дочерним компонентам:
Таким же образом это работает и для пользовательских компонентов:
Это принято называть «сверху-вниз», «нисходящим» или однонаправленным потоком данных. Любое состояние всегда находится во владении какого-либо компонента. Любые данные или UI, производные от этого состояния могут передаваться только в компоненты «ниже» их в дереве иерархии.
Если представить дерево компонентов как «водопад» свойств, то состояние каждого компонента является подобием дополнительного источника воды, который соединяется с водопадом в произвольной точке и также течет вниз.
Каждый компонент устанавливает своё собственное значение и обновляется независимо.
В приложениях React, независимо от того, обладает ли компонент состоянием – состояние является деталью реализации этого компонента и может изменяться со временем. Вы можете использовать компоненты без состояния внутри компонентов, имеющих состояние, и наоборот.
React State с нуля
Дата публикации: 2018-04-10
От автора: как только вы приступите к изучению React, вы столкнетесь с понятием state. State имеет огромное значение в React. Возможно, это первая причина, почему вы стали изучать React. Давайте рассмотрим понятие React state и принцип его работы.
Что такое state?
State (состояние) в React – это объект простого JS, позволяющий отслеживать данные компонента. Состояние компонента может меняться. Смена состояния компонента зависит от функциональности приложения. Изменения могут основываться на ответе от пользователя, новых сообщениях с сервера, ответа сети и т.д.
Состояние компонента должно быть приватным для компонента и контролироваться им. Изменения состояния компонента необходимо делать внутри компонента – инициализация и обновление состояния компонента.
Компоненты класса
Состояния доступны только для компонентов класса. Главная причина, почему вы захотите использовать компоненты класса, а не функциональные компоненты заключается в том, что компоненты класса могут обладать состоянием. Давайте разберемся, в чем разница. Функциональные компоненты – это JS функции:
Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения