Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Strict mode і подвійний рендер». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)React **спеціально робить подвійний рендер у дев-режимі**, щоб **допомогти тобі виявити помилки та побічні ефекти** (side effects) у функціях компонентів, які **не повинні впливати на результат рендера**. **Ключове:** це поведінка `<React.StrictMode>`, увімкнена тільки в режимі розробки, і вона не відбувається в продакшені.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Коротка відповідь React **спеціально робить подвійний рендер у дев-режимі**, щоб **допомогти тобі виявити помилки і побічні ефекти** (side effects) у функціях компонентів, які **не повинні впливати на результат рендера**. Ця поведінка увімкнена **тільки в режимі розробки**, і **не відбувається в продакшені**. --- ## Хто "винен" - Strict Mode Подвійний рендер у React Dev відбувається через компонент `<React.StrictMode>`, який за замовчуванням обгортає весь застосунок у `create-react-app`, Next.js та інших CLI. ```javascript const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> ); ``` --- ## Що робить StrictMode React.StrictMode - це **інструмент для розробників**, який: 1. **Викликає компоненти двічі** (в dev) → щоб перевірити, чи немає побічних ефектів у їхньому тілі. 2. **Викликає** `useEffect` **і** `useLayoutEffect` **двічі** → щоб переконатися, що cleanup працює коректно. 3. **Викликає** `constructor`**,** `render`**,** `useMemo`**,** `useCallback`**,** `useState` **тощо** двічі → з метою тестування чистоти функцій. --- ## Що таке "чиста функція" у контексті React Компонент React - це **чиста функція від своїх props і state**: вона повинна **повертати один і той самий JSX** при однакових вхідних даних і **не викликати побічні ефекти** (запити, таймери, мутації тощо) у тілі самої функції. Приклад "брудного" компонента: ```javascript function Timer() { console.log('Запуск таймера'); setInterval(() => console.log('tick'), 1000); return <p>Таймер</p>; } ``` Тут побічний ефект (`setInterval`) викликається прямо під час рендера. React при подвійному виклику покаже, що: - створюється **два таймери**, - і один з них **не очищається** - що є помилкою логіки. --- ## Приклад подвійного рендера ```javascript function Example() { console.log('Рендер компонента'); return <div>Hello</div>; } ``` У дев-режимі ти побачиш у консолі: ```javascript Рендер компонента Рендер компонента ``` А в **продакшені** (або якщо прибрати `<StrictMode>`) - тільки один виклик. --- ## Навіщо React робить це | Мета | Що перевіряє | |---|---| | Перевірити чистоту компонентів | Чи немає побічних ефектів при рендері | | Перевірити коректність cleanup в ефектах | `useEffect` і `useLayoutEffect` викликаються двічі | | Допомогти відловити помилки до продакшену | Наприклад, витоки пам'яті, дублюючі підписки | | Попередити антипатерни | Виклики API, таймери, мутації в тілі компонента | --- ## Які саме методи React дублює У **StrictMode (тільки dev):** - Викликаються повторно: - функції компонентів; - `useState` (ініціалізація); - `useReducer` (ініціалізація); - `useMemo` (ініціалізація); - `useEffect` (mount → unmount → mount); - `useLayoutEffect` (аналогічно). - Не викликаються повторно: - `componentDidCatch`; - `getDerivedStateFromError` (щоб не ламати обробку помилок); - події і реальні DOM-операції (вони виконуються один раз). --- ## Як це виглядає покроково 1. React викликає компонент → робить "віртуальний" рендер. 2. Одразу ж **розмонтовує** його (викличе cleanup ефектів). 3. Знову **монтує** його з нуля. Все це відбувається **в пам'яті**, без повторної зміни DOM, тому інтерфейс **не "блимає"** - тільки консоль покаже повторні виклики. --- ## Як вимкнути подвійний рендер Щоб тимчасово прибрати подвійні виклики - просто прибери StrictMode: ```javascript root.render( // Без <React.StrictMode> <App /> ); ``` Але це **не рекомендується**: > StrictMode допомагає виявити помилки ще до продакшену. > Краще виправити код, щоб він був "чистим". --- ## Як писати код, що правильно працює в StrictMode Дозволено: ```javascript function Component() { const [count, setCount] = useState(0); useEffect(() => { const id = setInterval(() => setCount(c => c + 1), 1000); return () => clearInterval(id); // cleanup! }, []); return <div>{count}</div>; } ``` Не можна: ```javascript function Component() { // Побічний ефект у тілі функції setInterval(() => console.log('tick'), 1000); return <div>Hello</div>; } ``` --- ## Підсумок | Питання | Відповідь | |---|---| | Чому подвійний рендер? | Через `<React.StrictMode>` | | Коли відбувається? | Тільки в dev-режимі | | Навіщо це потрібно? | Щоб знаходити побічні ефекти і помилки в компонентах | | Чи відбувається в продакшені? | Ні | | Як вимкнути? | Прибрати `<React.StrictMode>` (але краще не варто) |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.