← Назад к вопросам

Что возвращает useState?

1.2 Junior🔥 241 комментариев
#React

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что возвращает useState

useState — это один из самых базовых хуков React. Понимать его работу критически важно для любого React разработчика.

Базовый ответ

useState возвращает массив из двух элементов:

  1. Текущее значение состояния — переменная с данными
  2. Функция для обновления состояния — функция-сеттер
// Синтаксис
const [state, setState] = useState(initialValue);

// Пример
const [count, setCount] = useState(0);
//     ^      ^          ^
//     |      |          иниициальное значение
//     |      сеттер
//     состояние

Распаковка массива с деструктуризацией

Это именно массив, поэтому ты можешь распаковать его как хочешь:

// Стандартный способ (деструктуризация)
const [count, setCount] = useState(0);

// Без деструктуризации (редко используется)
const stateArray = useState(0);
const count = stateArray[0];
const setCount = stateArray[1];

// С произвольными именами
const [number, updateNumber] = useState(0);
const [isVisible, toggleVisibility] = useState(false);

Что возвращает сеттер

Функция-сеттер может быть вызвана двумя способами:

1. С новым значением напрямую:

const [count, setCount] = useState(0);

setCount(5); // устанавливает count = 5
setCount(count + 1); // устанавливает count = 1 (count было 0)

2. С функцией обновления (更функция обновления):

const [count, setCount] = useState(0);

// Функция обновления получает предыдущее значение
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount * 2);

Почему нужна функция обновления

Проблема: React батчит обновления, поэтому несколько setState могут работать с одним старым значением.

const [count, setCount] = useState(0);

const increment = () => {
  setCount(count + 1); // используем текущий count
  setCount(count + 1); // используем ТОТ ЖЕ count!
  // count станет 1, а не 2!
};

const betterIncrement = () => {
  setCount(prev => prev + 1); // использует текущее
  setCount(prev => prev + 1); // использует обновлённое
  // count станет 2!
};

Возврат значения из setState

АТЕНЦИОН: setState ничего не возвращает (возвращает undefined)!

const [count, setCount] = useState(0);

const result = setCount(5);
console.log(result); // undefined

// setState работает через побочный эффект
// Обновляет состояние, затем триггерит re-render

Это НЕ как обычная функция, которая возвращает результат. setState — это функция побочного эффекта.

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

// ✅ Правильно — в компоненте на верхнем уровне
function MyComponent() {
  const [count, setCount] = useState(0);
  return <div>{count}</div>;
}

// ✅ Правильно — в кастомном хуке
function useCounter() {
  const [count, setCount] = useState(0);
  return [count, setCount];
}

// ❌ Неправильно — в условии
function BadComponent(shouldHave) {
  if (shouldHave) {
    const [state, setState] = useState(0); // НЕЛЬЗЯ!
  }
}

// ❌ Неправильно — в цикле
function BadComponent(items) {
  return items.map(() => {
    const [state, setState] = useState(0); // НЕЛЬЗЯ!
  });
}

// ❌ Неправильно — в функции обработчика
function BadComponent() {
  const handleClick = () => {
    const [state, setState] = useState(0); // НЕЛЬЗЯ!
  };
}

Тип возвращаемого значения (TypeScript)

// useState возвращает кортеж [значение, сеттер]
const [count, setCount] = useState<number>(0);
// Тип: [number, Dispatch<SetStateAction<number>>]

const [name, setName] = useState<string>("John");
// Тип: [string, Dispatch<SetStateAction<string>>]

const [items, setItems] = useState<Item[]>([]);
// Тип: [Item[], Dispatch<SetStateAction<Item[]>>]

Частые ошибки

Ошибка 1: Мутация состояния напрямую

// ❌ Плохо — мутируешь массив
const [items, setItems] = useState([1, 2, 3]);
items.push(4); // НЕЛЬЗЯ! Не триггерит re-render

// ✅ Хорошо — создаёшь новый массив
setItems([...items, 4]);

Ошибка 2: Зависимость от асинхронности

// ❌ Плохо
const [count, setCount] = useState(0);
setCount(1);
console.log(count); // ещё 0! setState асинхронный

// ✅ Хорошо
const [count, setCount] = useState(0);
useEffect(() => {
  console.log(count); // теперь 1
}, [count]);

Ошибка 3: Забыл распаковать массив

// ❌ Плохо
const state = useState(0);
state[0]; // получаешь функцию, а не значение!

// ✅ Хорошо
const [count, setCount] = useState(0);

Если нужны несколько состояний

Не сбрасывай всё в один объект — используй несколько useState:

// ❌ Плохо — всё в одном
const [state, setState] = useState({ count: 0, name:  });
setState({ ...state, count: state.count + 1 });

// ✅ Хорошо — отдельные хуки
const [count, setCount] = useState(0);
const [name, setName] = useState();
setCount(count + 1);

Итог

useState возвращает [текущее значение, функция обновления]. Функция обновления:

  • Не возвращает ничего (undefined)
  • Может принять значение или функцию обновления
  • Триггерит re-render компонента
  • Работает асинхронно

Это основа React, и если ты его понял — всё остальное будет проще.