Skip to main content

Що означає "state lifting" (підйом стану)?

Що таке "підйом стану" (state lifting)

State lifting - це перенесення (підйом) стану з дочірнього компонента в його батька, щоб кілька компонентів могли ділитися спільними даними або синхронізуватися між собою.


Приклад проблеми

Уяви, у нас є два поля вводу: одне - у градусах Цельсія, інше - у Фаренгейтах. Кожне зберігає свій локальний стан.

javascript
function CelsiusInput() { const [celsius, setCelsius] = useState(""); return <input value={celsius} onChange={e => setCelsius(e.target.value)} />; } function FahrenheitInput() { const [fahrenheit, setFahrenheit] = useState(""); return <input value={fahrenheit} onChange={e => setFahrenheit(e.target.value)} />; }

Проблема: Якщо користувач змінить Цельсій, Фаренгейт не оновиться. Два компоненти не синхронізовані, тому що в кожного свій стан.


Рішення - підняти стан вище (у батька)

Перенесемо спільний стан у батьківський компонент, а дочірнім передамо його через props.

javascript
function TemperatureConverter() { const [celsius, setCelsius] = useState(""); const fahrenheit = (celsius * 9) / 5 + 32; return ( <div> <CelsiusInput value={celsius} onChange={setCelsius} /> <FahrenheitDisplay value={fahrenheit} /> </div> ); } function CelsiusInput({ value, onChange }) { return ( <input value={value} onChange={(e) => onChange(e.target.value)} placeholder="°C" /> ); } function FahrenheitDisplay({ value }) { return <p>{value} °F</p>; }

Тепер у нас одне джерело істини - celsius у батька, і обидва компоненти синхронізовані.


Візуально

javascript
До lifting: [Child1: has state] [Child2: has state] розсинхронізація Після lifting: [Parent: has state] ├── [Child1: отримує через props] └── [Child2: отримує через props] синхронізовано

Коли потрібен state lifting

Використовуй "підйом стану", коли:

  • кілька компонентів залежать від одних і тих же даних;
  • потрібно, щоб одна зміна впливала на інші;
  • стан "належить" не тільки одному компоненту.

Приклад 1 - форма і передперегляд

javascript
function App() { const [text, setText] = useState(""); return ( <> <Input value={text} onChange={setText} /> <Preview text={text} /> </> ); }

text піднятий в App, і тепер Input і Preview працюють з одними даними.


Приклад 2 - фільтрація і список

javascript
function App() { const [filter, setFilter] = useState(""); const items = ["apple", "banana", "grape"]; const filtered = items.filter(item => item.includes(filter)); return ( <> <Search value={filter} onChange={setFilter} /> <List items={filtered} /> </> ); }

Тепер зміна поля пошуку впливає на список. Якби Search і List мали свої стани, вони б "жили окремо".


Відмінність від state colocation

КонцепціяСуть
State colocation"Зберігай стан якомога ближче до місця використання."
State lifting"Якщо стан потрібен кільком компонентам, підніми його туди, де вони перетинаються."

Ідеально, коли ці принципи в рівновазі:

  • стан не занадто високо (щоб не було зайвих ререндерів),
  • але й не занадто низько (щоб не дублювати дані).

Помилки при підйомі стану

ПомилкаЧому погано
Підняв занадто високоВикличе ререндер усіх дочірніх компонентів
Не підняв взагаліДані дублюються, розсинхронізація
Змінюєш стан з "не власника"Порушує принцип односпрямованого потоку даних

Практичний патерн

Якщо тобі потрібно "передати вгору" нове значення з дочірнього компонента, використовуй callback (функцію з props):

javascript
function Child({ onChange }) { return <input onChange={(e) => onChange(e.target.value)} />; }

Батько вирішує, що робити з новим значенням. Дочірній компонент просто "повідомляє про подію".


Підсумок

ПитанняВідповідь
Що таке state lifting?Перенесення стану з дочірнього компонента в батька
Навіщо?Щоб кілька компонентів могли синхронізуватися
Як реалізується?Через props і callback-и
Коли потрібен?Коли кілька компонентів залежать від одних даних
Як пов'язаний з colocation?Піднімаємо лише настільки, наскільки потрібно, не вище
Головна метаОдне "джерело істини" для пов'язаних компонентів

Проста аналогія

Кожен компонент - це "кімната".

Коли два пристрої в різних кімнатах мають працювати з одним пультом, логічно підняти пульт нагору, у коридор, щоб ним могли користуватися обидва.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.