Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чому не варто зберігати у стані те, що можна обчислити?

Надлишковий стан - значення, яке можна обчислити з props чи іншого стану. Його зберігання - джерело помилок, бо дві копії правди рано чи пізно розходяться.

Погано:

const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [fullName, setFullName] = useState('');   // надлишкове

function handleFirstNameChange(e) {
  setFirstName(e.target.value);
  setFullName(e.target.value + ' ' + lastName);   // треба не забути оновити тут
}

Добре - обчислювати під час рендеру:

const fullName = `${firstName} ${lastName}`;

Типові випадки надлишкового стану:

  • відфільтрований чи відсортований список поруч з оригіналом:
const visibleTodos = todos.filter((t) => (showDone ? true : !t.done));
  • кількості й суми: items.length, items.reduce(...);
  • обраний елемент як копія об'єкта - краще зберігати selectedId і знаходити об'єкт: items.find((i) => i.id === selectedId). Інакше зміна елемента в списку не потрапить у «обраний»;
  • прапорці, що випливають з даних: isEmpty, hasErrors, canSubmit.

Антипатерн - синхронізація ефектом:

const [visibleTodos, setVisibleTodos] = useState([]);
useEffect(() => {
  setVisibleTodos(todos.filter(...));
}, [todos]);

Зайвий рендер зі старими даними, потім ще один - з новими. Плюс місце для помилки, якщо забути залежність.

А якщо обчислення дороге? Спершу виміряти. Якщо справді повільно - useMemo (або React Compiler зробить це автоматично):

const visibleTodos = useMemo(() => filterTodos(todos, query), [todos, query]);

Коли копія з props доречна: коли це початкове значення, яке далі живе своїм життям, - і тоді props варто назвати відповідно (initialColor, defaultValue), щоб було зрозуміло, що подальші зміни props не враховуються.

Перевірка структури стану: для кожного значення в useState запитати: «чи можна його обчислити з інших?». Якщо так - це не стан.

Докладніше в документації: Вибір структури стану

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання