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

Що означає «підняти стан угору» і коли це потрібно?

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

Було - кожна панель сама вирішує, чи відкрита:

function Panel({ title, children }) {
  const [isOpen, setIsOpen] = useState(false);
  // ...
}

Вимога «відкрита лише одна панель одночасно» так не реалізується: панелі не знають одна про одну.

Стало - стан у батька, панелі керовані:

function Accordion() {
  const [openId, setOpenId] = useState('about');

  return (
    <>
      <Panel title="Про нас" isOpen={openId === 'about'} onOpen={() => setOpenId('about')}>...</Panel>
      <Panel title="Доставка" isOpen={openId === 'delivery'} onOpen={() => setOpenId('delivery')}>...</Panel>
    </>
  );
}

function Panel({ title, isOpen, onOpen, children }) {
  return (
    <section>
      <button onClick={onOpen}>{title}</button>
      {isOpen && children}
    </section>
  );
}

Panel став керованим (controlled): ним керує батько через props. Компонент зі своїм внутрішнім станом - некерований (uncontrolled).

Принцип «одного джерела правди»: для кожного шматка стану є один компонент-власник. Інші отримують значення через props і повідомляють про зміни через колбеки.

Куди піднімати:

  • до найближчого спільного предка всіх, хто використовує дані, - не вище. Стан занадто високо змушує перерендерюватися велику частину дерева й ускладнює компоненти;
  • якщо спільний предок дуже далеко і дані треба передавати через багато рівнів («prop drilling»), - спершу композиція (передати готовий JSX через children), потім Context.

Зворотний процес теж корисний: якщо стан використовується лише в одному компоненті, його варто опустити туди (state colocation) - менше зайвих рендерів і простіші батьки.

Типова помилка - дублювати стан: копіювати props у локальний стан дитини (useState(props.value)). Копія не оновиться, коли батько змінить значення. Або компонент керований (значення з props), або некерований (власний стан з початковим значенням), - змішування дає розсинхронізацію.

Докладніше в документації: Спільний стан між компонентами

Перевір себе

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

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