React useState

Хук useState позволяет отслеживать состояние в функциональном компоненте.

Состояние обычно относится к данным или свойствам, которые необходимо отслеживать в приложении.


Импорт useState

Чтобы использовать хук useState, сначала нужно импортировать его в компонент при помощи инструкции import.

Пример

В верхней части компонента импортируйте хук useState.


import { useState } from "react";

Обратите внимание, что мы диструктурируем useState из библиотеки react, так как это именованный экспорт.

Узнать больше о деструктурировании можно в разделе "ES6 Деструктуризация".

Инициализация useState

Мы можем инициализировать состояние, вызвав useState в функциональном компоненте.

useState принимает начальное состояние и возвращает два значения:

  1. Текущее состояние.
  2. Функцию для обновления состояния.

Пример

Инициализируем состояние вверху функционального компонента.


import { useState } from "react";

function FavoriteColor() {
  const [color, setColor] = useState("red");
}

Обратите внимание, что снова мы выполняем деструктуризацию возвращаемых значений из useState.

Первое значение, color, — это текущее состояние.

Второе значение, setColor, — это функция, используемая для обновления состояния.

Эти имена - это переменные, и они могут называться любыми именами на ваш выбор.

Наконец, мы устанавливаем начальное состояние равным "red": useState("red").


Чтение состояния

Теперь мы можем использовать состояние в любом месте нашего компонента.

Пример

Используем переменную состояния в рендеринге компонента.


import { useState } from 'react';
import { createRoot } from 'react-dom/client';

function FavoriteColor() {
  const [color, setColor] = useState("red");

  return <h1>Мой любимый цвет — {color}!</h1>
}

createRoot(document.getElementById('root')).render(
  <FavoriteColor />
);


Обновление состояния

Чтобы обновить состояние, мы используем нашу функцию обновления состояния.

Пример

Используем функцию обновления состояния для изменения состояния:


<button
  type="button"
  onClick={() => setColor("blue")}
>Синий</button>

Никогда не следует напрямую обновлять состояние. Например, недопустимо присваивать значение напрямую: color = "blue".

Пример

Используем кнопку для обновления состояния:


import { useState } from 'react';
import { createRoot } from 'react-dom/client';

function FavoriteColor() {
  const [color, setColor] = useState("red");

  return (
    <>
      <h1>Мой любимый цвет — {color}!</h1>
      <button
        type="button"
        onClick={() => setColor("blue")}
      >Синий</button>
    </>
  )
}

createRoot(document.getElementById('root')).render(
  <FavoriteColor />
);


Какие типы данных может хранить состояние?

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

Мы могли бы создать несколько хуков useState для отслеживания индивидуальных значений.

Пример

Создание нескольких хуков useState:


import { useState } from 'react';
import { createRoot } from 'react-dom/client';

function MyCar() {
  const [brand, setBrand] = useState("Ford");
  const [model, setModel] = useState("Mustang");
  const [year, setYear] = useState("1964");
  const [color, setColor] = useState("red");

  return (
    <>
      <h1>Моя машина — {brand}</h1>
      <p>
        Это {color}-цветный {model}, выпущенный в {year} году.
      </p>
    </>
  )
}

createRoot(document.getElementById('root')).render(
  <MyCar />
);

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

Пример

Создание единственного хука, хранящего объект:


import { useState } from 'react';
import { createRoot } from 'react-dom/client';

function MyCar() {
  const [car, setCar] = useState({
    brand: "Ford",
    model: "Mustang",
    year: "1964",
    color: "red"
  });

  return (
    <>
      <h1>Моя машина — {car.brand}</h1>
      <p>
        Это {car.color}-цветный {car.model}, выпущенный в {car.year} году.
      </p>
    </>
  )
}

createRoot(document.getElementById('root')).render(
  <MyCar />
);

Так как теперь мы отслеживаем единственный объект car, нам нужно ссылаться на этот объект при рендеринге компонента (например, car.brand).

Обновление объектов и массивов в состоянии

Когда состояние обновляется, старое состояние полностью замещается новым значением.

Что если мы хотим обновить только цвет машины?

Если вызвать setCar({color: "blue"}), это приведет к потере полей brand, model и year из состояния.

Решить такую проблему можно с помощью оператора распространения JavaScript.

Пример

Используем оператор распространения JavaScript для обновления только цвета машины:


const updateColor = () => {
  setCar(previousState => {
    return { ...previousState, color: "blue" }
  });
}

Так как нам необходимо текущее значение состояния, мы передаем функцию в наш метод setCar. Эта функция получает предыдущее значение.

Затем мы возвращаем объект, распространяя предыдущие значения previousState и перео0пределяя только цвет.