Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что возвращает useState
useState — это один из самых базовых хуков React. Понимать его работу критически важно для любого React разработчика.
Базовый ответ
useState возвращает массив из двух элементов:
- Текущее значение состояния — переменная с данными
- Функция для обновления состояния — функция-сеттер
// Синтаксис
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, и если ты его понял — всё остальное будет проще.