Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Чому важливо вказувати всі залежності ефекту?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Залежності** - це всі значення, які твій ефект використовує всередині себе (змінні, пропси, функції, стан тощо); React перезапускає ефект лише тоді, коли одна з них змінюється. **Ключове:** якщо не вказати залежність, React підставить застарілу версію цієї змінної, і ефект працюватиме зі "замороженими" старими даними.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке залежності ефекту Залежності - це **всі значення, які твій ефект використовує всередині себе** (змінні, пропси, функції, стан тощо). ```javascript useEffect(() => { console.log(count); // ← залежність }, [count]); ``` React буде **перезапускати ефект лише тоді**, коли `count` зміниться. --- ## Чому важливо вказувати всі залежності Тому що React **"запам'ятовує"** значення змінних, які були під час останнього рендера. Якщо ти не вкажеш залежність, React підставить **стару ("застарілу") версію** цієї змінної. --- ### Приклад з помилкою ```javascript function Example() { const [count, setCount] = useState(0); useEffect(() => { const id = setInterval(() => { console.log(count); // завжди 0! setCount(count + 1); }, 1000); }, []); // ← count не вказано! return <p>{count}</p>; } ``` Що відбувається: - `useEffect` виконається один раз під час монтування. - Замикання "спіймає" значення `count = 0`. - Через секунду знову і знову викликатиметься `setCount(0 + 1)`. - Але всередині ефекту `count` **не оновлюється**, тому що ефект не перезапускається. → Результат - **"застаріле замикання"** і некоректна поведінка. --- ### Правильно: ```javascript useEffect(() => { const id = setInterval(() => { setCount(c => c + 1); // використовуємо функціональне оновлення }, 1000); return () => clearInterval(id); }, []); // тепер залежності не потрібні ``` або, якщо всередині ефекту залежність використовується напряму: ```javascript useEffect(() => { console.log("Count:", count); }, [count]); // вказали залежність ``` --- ## Що буде, якщо залежність пропустити | Сценарій | Що станеться | |---|---| | Залежність не вказана | Ефект використовуватиме застаріле значення | | Залежність змінюється, але не вказана | React не перезапустить ефект → помилка логіки | | Усі залежності вказані | Ефект коректно реагує на зміни даних | --- ## Як React допомагає React постачається з лінтером: ```javascript npm install eslint-plugin-react-hooks --save-dev ``` І в `.eslintrc`: ```javascript { "plugins": ["react-hooks"], "rules": { "react-hooks/exhaustive-deps": "warn" } } ``` Він підкаже, якщо ти забув щось вказати: ```javascript React Hook useEffect has a missing dependency: 'count'. Either include it or remove the dependency array. ``` --- ## Поради **Вказуй усе, що використовується всередині ефекту**, крім: - констант і вбудованих API (наприклад, `window`, `document`), - значень, які заздалегідь не змінюються (наприклад, рефи). Якщо не хочеш залежати від змінної, використовуй **функціональне оновлення** (`setState(prev => ...)`). Не бійся "зайвих" залежностей - **React гарантує оптимізацію**. Головне - **передбачуваність** і відсутність прихованих багів. --- ## Підсумок | Питання | Відповідь | |---|---| | Чому важливо вказувати всі залежності | Щоб React знав, коли потрібно оновити ефект, і не використовував застарілі значення | | Що буде, якщо не вказати | Ефект працюватиме із "замороженими" старими даними | | Як правильно | Вказувати всі значення, які використовуються всередині ефекту | | Як собі допомогти | Використовувати ESLint-плагін `react-hooks/exhaustive-deps` |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.