Что такое useState и как он работает?

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

Что делает useState

Когда вы вызываете useState, вы создаёте переменную состояния, которая сохраняет своё значение между перерендериваниями компонента. Вместе с этой переменной вы получаете функцию для её обновления. При вызове этой функции React:

  • сохраняет новое значение,

  • инициирует повторный рендер компонента с новым значением.

Синтаксис

const \[state, setState\] = useState(initialValue);
  • state — текущее значение состояния;

  • setState — функция, которая обновляет это значение;

  • initialValue — начальное значение (0, '', {}, [], true и т.д.).

Простой пример

import React, { useState } from 'react';
import { View, Text, Button } from 'react-native';
export default function Counter() {
const \[count, setCount\] = useState(0);
return (
<View>
<Text>Счётчик: {count}</Text>
<Button title="Увеличить" onPress={() => setCount(count + 1)} />
</View>
);
}
  • count инициализируется как 0;

  • при нажатии кнопки вызывается setCount(count + 1);

  • компонент повторно рендерится, отображая обновлённое значение.

Как работает под капотом

  • При первом рендере React вызывает useState(0) и сохраняет 0 как начальное значение.

  • При каждом обновлении состояния с помощью setCount, React добавляет новое значение в очередь, затем повторно вызывает компонент с новым значением count.

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

Несколько состояний

Можно вызывать useState столько раз, сколько нужно:

const \[name, setName\] = useState('');
const \[age, setAge\] = useState(18);
const \[isOnline, setIsOnline\] = useState(false);

Каждое состояние независимо, React отслеживает их порядок и связывает значение с нужным вызовом.

Правила использования useState

  1. useState можно вызывать только внутри функционального компонента или кастомного хука.

  2. Нельзя вызывать useState:

    • внутри условий (if),

    • внутри циклов (for, map),

    • внутри вложенных функций или обработчиков.

  3. Порядок вызова хуков должен быть одинаковым на каждом рендере, иначе React "путается", какое состояние к какому хуку относится.

Ленивая инициализация

Если начальное значение вычисляется сложно, можно использовать функцию:

const \[value, setValue\] = useState(() => {
console.log('Вычисление значения один раз');
return expensiveCalculation();
});

React вызовет эту функцию только при первом рендере, а не при каждом.

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

Прямое обновление:

setCount(count + 1);

Функциональное обновление (рекомендуется при зависимости от предыдущего состояния):

setCount(prevCount => prevCount + 1);

Это особенно важно при асинхронных событиях, когда вы не уверены, какое именно значение было на момент вызова setCount.

Обновление сложных объектов

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

const \[user, setUser\] = useState({ name: 'Алиса', age: 25 });
setUser(prev => ({
...prev,
age: prev.age + 1
}));

Почему? Потому что React сравнивает по ссылке, а не по значению. Только новый объект (новая ссылка) вызывает повторный рендер.

Обновление массивов

const \[items, setItems\] = useState(\[\]);
const addItem = (newItem) => {
setItems(prev => \[...prev, newItem\]);
};

Как и в случае с объектами, массивы тоже нужно копировать при обновлении.

Повторный рендер

Каждый раз при вызове setState, React перерисовывает весь компонент, чтобы отобразить актуальные данные.

  • Это не обновляет DOM напрямую — React сначала обновляет виртуальный DOM, затем сравнивает его с предыдущим состоянием и обновляет только изменённые элементы.

  • Перерисовка происходит асинхронно, React может объединять несколько setState вызовов для оптимизации.

Связь useState с TextInput

Хранение значения поля ввода:

const \[name, setName\] = useState('');
<TextInput
value={name}
onChangeText={setName}
/>

Каждое изменение текста вызывает setName, и value обновляется. Это называется управляемым компонентом.

Сброс значения

setName(''); // сбрасывает поле

Типы значений в useState

React допускает любые типы данных:

  • строки

  • числа

  • boolean

  • массивы

  • объекты

  • null, undefined

  • функции (если не ленивая инициализация, функция будет значением, а не вызовом)

Сравнение с this.state и this.setState (в классовых компонентах)

useState this.state / this.setState
Где используется В функциональных компонентах В классовых компонентах
--- --- ---
Инициализация useState(initialValue) this.state = { ... } в конструкторе
--- --- ---
Обновление setState(newValue) this.setState({ key: value })
--- --- ---
Асинхронность Да Да
--- --- ---
Автоматическое слияние Нет (нужно вручную объединять) Да (объединяется автоматически)
--- --- ---
Сколько состояний Неограниченно Одно дерево состояния
--- --- ---

useState vs useReducer

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

Пример — корзина товаров, формы с валидацией, сложные сценарии переключения состояний.

Хуки и локальное состояние

  • Состояние, созданное с useState, привязано к конкретному экземпляру компонента.

  • Если компонент размонтируется, состояние уничтожается.

  • При новом монтировании — useState снова инициализируется.

useState — это фундаментальный хук, который позволяет управлять состоянием в React-функциях, делая их мощными и гибкими инструментами для построения интерактивных интерфейсов.