> Какое initial value можно передать в useState в React? (React)

Уровень: middle · Роль: frontend · Категория: Технические вопросы

Компании: Сбер

Стек: React

> Пример ответа

Короткий ответ

В useState можно передать любое значение: примитив (число, строку, boolean, null, undefined, symbol, bigint), объект, массив, функцию. Если передать функцию, React вызовет её один раз при инициализации и использует возвращённое значение как начальное состояние. Также можно передать ленивый инициализатор - функцию, которая вычисляет начальное значение только при первом рендере.

Подробное объяснение

useState принимает один аргумент - initial value. Это может быть:

  • Примитив: 0, 'text', true, null, undefined
  • Ссылочный тип: объект {}, массив [], функция
  • Ленивый инициализатор: функция, которая возвращает значение. React вызывает её только при первом рендере компонента, игнорируя при последующих обновлениях

Если передать функцию напрямую как значение (например, useState(someFunc)), React воспримет её как ленивый инициализатор и вызовет её. Чтобы хранить функцию как состояние, нужно обернуть её в стрелочную функцию: useState(() => someFunc).

Для сложных вычислений начального состояния (например, чтение из localStorage, парсинг JSON, сложные математические операции) рекомендуется использовать ленивый инициализатор, чтобы избежать повторных вычислений при каждом рендере.

На практике

  • Для чисел, строк и boolean передавай значение напрямую: useState(0), useState(''), useState(false)
  • Для объектов и массивов используй литералы: useState({ count: 0 }), useState([])
  • Если начальное состояние требует дорогих вычислений, используй ленивый инициализатор: useState(() => expensiveComputation())
  • Для хранения функции как состояния оборачивай в стрелочную функцию: useState(() => () => console.log('hello'))
  • undefined как initial value - допустимо, но состояние будет undefined. Часто используется для обозначения "ещё не загружено"

Пример кода

JSX
// Примитивы
const [count, setCount] = useState(0);
const [name, setName] = useState('John');
const [isActive, setIsActive] = useState(false);
// Ссылочные типы
const [user, setUser] = useState({ name: '', age: 0 });
const [items, setItems] = useState([]);
// Ленивый инициализатор - вычисляется один раз
const [data, setData] = useState(() => {
const saved = localStorage.getItem('data');
return saved ? JSON.parse(saved) : [];
});
// Функция как состояние
const [callback, setCallback] = useState(() => () => {});

Как отвечать на собеседовании

Начни с того, что useState принимает любое значение, включая примитивы, объекты, массивы и функции. Обязательно упомяни ленивый инициализатор и его преимущества для дорогих вычислений. Приведи пример, когда функция передаётся как значение состояния - это частый подвох. Покажи понимание разницы между useState(someFunc) и useState(() => someFunc). Закончи практическим советом: для сложных начальных значений используй ленивый инициализатор, чтобы избежать лишних вычислений при ререндерах.

Что проверяет интервьюер

  • Понимание базового API хука useState
  • Знание особенностей передачи функции как initial value
  • Понимание ленивой инициализации и её performance-преимуществ
  • Умение различать случаи, когда функция - это значение состояния, а когда - инициализатор
  • Практический опыт работы с различными типами начальных состояний

Типичные ошибки

  • Передача функции напрямую, когда нужно хранить её как значение: useState(myFunc) вместо useState(() => myFunc)
  • Использование дорогих вычислений в initial value без ленивого инициализатора: useState(expensiveComputation()) - будет вызываться при каждом рендере
  • Передача объекта или массива, который создаётся каждый раз заново - это нормально, но может быть неочевидно для новичков
  • Забывание, что null и undefined - допустимые значения, и их можно использовать как начальное состояние для обозначения "пустого" состояния

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью