{"componentChunkName":"component---src-templates-docs-js","path":"/docs/hooks-faq.html","result":{"data":{"markdownRemark":{"html":"<p><em>Хуки</em> — це новинка в React 16.8. Вони дозволяють вам використовувати стан та інші можливості React без написання класу.</p>\n<p>На цій сторінці ви знайдете відповіді на деякі поширені питання щодо <a href=\"/docs/hooks-overview.html\">хуків</a>.</p>\n<!--\n  якщо вам доведеться колись згенерувати це заново, наступний уривок коду, введений у інструменти розробника, може вам допомогти:\n\n  $$('.anchor').map(a =>\n    `${' '.repeat(2 * +a.parentNode.nodeName.slice(1))}` +\n    `[${a.parentNode.textContent}](${a.getAttribute('href')})`\n  ).join('\\n')\n-->\n<ul>\n<li>\n<p><strong><a href=\"#adoption-strategy\">Стратегія впровадження хуків</a></strong></p>\n<ul>\n<li><a href=\"#which-versions-of-react-include-hooks\">Які версії React включають хуки?</a></li>\n<li><a href=\"#do-i-need-to-rewrite-all-my-class-components\">Чи маю я переписувати всі мої класові компоненти?</a></li>\n<li><a href=\"#what-can-i-do-with-hooks-that-i-couldnt-with-classes\">Що я можу зробити з хуками такого, чого не можу з класами?</a></li>\n<li><a href=\"#how-much-of-my-react-knowledge-stays-relevant\">Яка частина моїх знань React залишиться актуальною?</a></li>\n<li><a href=\"#should-i-use-hooks-classes-or-a-mix-of-both\">Що я маю використовувати: хуки, класи чи їх комбінацію?</a></li>\n<li><a href=\"#do-hooks-cover-all-use-cases-for-classes\">Чи покривають хуки всі варіанти використання класів?</a></li>\n<li><a href=\"#do-hooks-replace-render-props-and-higher-order-components\">Чи замінять хуки рендер пропси та компоненти вищого порядку?</a></li>\n<li><a href=\"#what-do-hooks-mean-for-popular-apis-like-redux-connect-and-react-router\">Що означають хуки для популярних API, таких як Redux connect() чи React Router?</a></li>\n<li><a href=\"#do-hooks-work-with-static-typing\">Чи працюють хуки зі статичною типізацією?</a></li>\n<li><a href=\"#how-to-test-components-that-use-hooks\">Як тестувати компоненти, які використовують хуки?</a></li>\n<li><a href=\"#what-exactly-do-the-lint-rules-enforce\">Що саме перевіряють правила лінтера у хуках?</a></li>\n</ul>\n</li>\n<li>\n<p><strong><a href=\"#from-classes-to-hooks\">Від класів до хуків</a></strong></p>\n<ul>\n<li><a href=\"#how-do-lifecycle-methods-correspond-to-hooks\">Як методи життєвого циклу співвідносяться з хуками?</a></li>\n<li><a href=\"#how-can-i-do-data-fetching-with-hooks\">Як я можу робити вибірку даних з допомогою хуків?</a></li>\n<li><a href=\"#is-there-something-like-instance-variables\">Чи є щось подібне до змінних екземпляра класу?</a></li>\n<li><a href=\"#should-i-use-one-or-many-state-variables\">Скільки змінних стану мені слід використовувати — одну чи декілька?</a></li>\n<li><a href=\"#can-i-run-an-effect-only-on-updates\">Чи можна запускати ефект лише при оновленні?</a></li>\n<li><a href=\"#how-to-get-the-previous-props-or-state\">Як отримати попередні пропси чи стан?</a></li>\n<li><a href=\"#why-am-i-seeing-stale-props-or-state-inside-my-function\">Чому я бачу застарілі значення пропсів чи стану всередині моєї функції?</a></li>\n<li><a href=\"#how-do-i-implement-getderivedstatefromprops\">Як я можу реалізувати getDerivedStateFromProps?</a></li>\n<li><a href=\"#is-there-something-like-forceupdate\">Чи є щось схоже на forceUpdate?</a></li>\n<li><a href=\"#can-i-make-a-ref-to-a-function-component\">Чи можу я зробити реф на функціональний компонент?</a></li>\n<li><a href=\"#how-can-i-measure-a-dom-node\">Як я можу обмежити вузол DOM?</a></li>\n<li><a href=\"#what-does-const-thing-setthing--usestate-mean\">Що означає const [thing, setThing] = useState()?</a></li>\n</ul>\n</li>\n<li>\n<p><strong><a href=\"#performance-optimizations\">Оптимізація продуктивності</a></strong></p>\n<ul>\n<li><a href=\"#can-i-skip-an-effect-on-updates\">Чи можу я пропустити ефект при оновленні?</a></li>\n<li><a href=\"#is-it-safe-to-omit-functions-from-the-list-of-dependencies\">Чи безпечно не вказувати в списку залежностей функції?</a></li>\n<li><a href=\"#what-can-i-do-if-my-effect-dependencies-change-too-often\">Що я можу зробити, якщо залежності мого ефекту змінюються надто часто?</a></li>\n<li><a href=\"#how-do-i-implement-shouldcomponentupdate\">Як я можу реалізувати shouldComponentUpdate?</a></li>\n<li><a href=\"#how-to-memoize-calculations\">Як запам’ятати обчислення?</a></li>\n<li><a href=\"#how-to-create-expensive-objects-lazily\">Як ліниво обчислити вартісні об’єкти?</a></li>\n<li><a href=\"#are-hooks-slow-because-of-creating-functions-in-render\">Чи є хуки повільними через створення функцій при рендері?</a></li>\n<li><a href=\"#how-to-avoid-passing-callbacks-down\">Як уникнути передачі функцій зворотнього виклику вниз?</a></li>\n<li><a href=\"#how-to-read-an-often-changing-value-from-usecallback\">Як прочитати часто змінюване значення з useCallback?</a></li>\n</ul>\n</li>\n<li>\n<p><strong><a href=\"#under-the-hood\">Деталі реалізації</a></strong></p>\n<ul>\n<li><a href=\"#how-does-react-associate-hook-calls-with-components\">Як React асоціює виклики хуків з компонентами?</a></li>\n<li><a href=\"#what-is-the-prior-art-for-hooks\">Що лежить в основі дизайну хуків?</a></li>\n</ul>\n</li>\n</ul>\n<h2 id=\"adoption-strategy\"><a href=\"#adoption-strategy\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Стратегія впровадження хуків </h2>\n<h3 id=\"which-versions-of-react-include-hooks\"><a href=\"#which-versions-of-react-include-hooks\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Які версії React включають хуки? </h3>\n<p>Починаючи з версії 16.8.0, React включає стабільну реалізацію хуків для:</p>\n<ul>\n<li>React DOM</li>\n<li>React Native</li>\n<li>React DOM Server</li>\n<li>Тестовий рендерер React</li>\n<li>Поверхневий рендерер React</li>\n</ul>\n<p>Зверніть увагу на те, <strong>що всі пакунки React мають бути версії 16.8.0 або вище, щоб підтримувати хуки</strong>. Хуки не будуть працювати, якщо ви забудете оновити, наприклад, React DOM.</p>\n<p><a href=\"https://reactnative.dev/blog/2019/03/12/releasing-react-native-059\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">React Native 0.59</a> версії 0.59 та вище підтримує хуки.</p>\n<h3 id=\"do-i-need-to-rewrite-all-my-class-components\"><a href=\"#do-i-need-to-rewrite-all-my-class-components\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи маю я переписувати всі мої класові компоненти? </h3>\n<p>Ні. Ми <a href=\"/docs/hooks-intro.html#gradual-adoption-strategy\">не плануємо</a> видаляти класи з React — нам потрібно поставляти програмні продукти і ми не можемо дозволити собі переписувати кодову базу. Ми рекомендуємо спробувати хуки у новому коді.</p>\n<h3 id=\"what-can-i-do-with-hooks-that-i-couldnt-with-classes\"><a href=\"#what-can-i-do-with-hooks-that-i-couldnt-with-classes\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Що я можу зробити з хуками такого, чого не можу з класами? </h3>\n<p>Хуки пропонують новий, потужний і виразний шлях для повторного використання функціональності між компонентами. <a href=\"/docs/hooks-custom.html\">“Створення користувацьких хуків”</a> надає уявлення того, що ви можете реалізувати. <a href=\"https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Ця стаття</a>, написана членом основної команди розробників React, детально розповідає про нові можливості, які відкривають хуки.</p>\n<h3 id=\"how-much-of-my-react-knowledge-stays-relevant\"><a href=\"#how-much-of-my-react-knowledge-stays-relevant\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Яка частина моїх знань React залишиться актуальною? </h3>\n<p>Хуки — це більш прямий спосіб використання особливостей React про які ви вже знаєте: стан, життєвий цикл, контекст і рефи. Хуки не змінюють основні принципи роботи React і ваші знання компонентів, пропсів та низхідного потоку даних залишаться актуальними.</p>\n<p>Хуки самі по собі мають криву вивчення. Якщо у цій документації чогось не вистачає, <a href=\"https://github.com/reactjs/reactjs.org/issues/new\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">підніміть питання</a> і ми спробуємо допомогти вам.</p>\n<h3 id=\"should-i-use-hooks-classes-or-a-mix-of-both\"><a href=\"#should-i-use-hooks-classes-or-a-mix-of-both\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Що я маю використовувати: хуки, класи чи їх комбінацію? </h3>\n<p>Коли ви будете готові, ми заохочуємо вас почати використовувати хуки у ваших нових компонентах. Впевніться, що кожен член вашої команди підтримує їх використання і ознайомлений з документацією. Ми не рекомендуємо переписувати існуючі класи з використанням хуків, якщо ви не плануєте їх переписувати у будь-якому випадку (наприклад, щоб виправити помилку).</p>\n<p>Ви не можете використовувати хуки <em>всередині</em> класового компонента, але ви безумовно можете комбінувати класи і функціональні компоненти з хуками в одному дереві. Чи є компонент класом, чи функцією — неважливо, оскільки це лише деталь реалізації цього компонента. Ми очікуємо, що в майбутньому хуки будуть основним методом написання React-компонентів.</p>\n<h3 id=\"do-hooks-cover-all-use-cases-for-classes\"><a href=\"#do-hooks-cover-all-use-cases-for-classes\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи покривають хуки всі варіанти використання класів? </h3>\n<p>Нашою метою є покриття всіх можливостей класів хуками якнайшвидше. Наразі немає альтернативи у вигляді хуків для таких рідковживаних методів життєвого циклу як <code class=\"gatsby-code-text\">getSnapshotBeforeUpdate</code>, <code class=\"gatsby-code-text\">getDerivedStateFromError</code> та <code class=\"gatsby-code-text\">componentDidCatch</code>, але ми плануємо скоро їх додати.</p>\n<p>Оскільки хуки з’явились зовсім нещодавно, то не всі сторонні бібліотеки можуть бути сумісними з ними.</p>\n<h3 id=\"do-hooks-replace-render-props-and-higher-order-components\"><a href=\"#do-hooks-replace-render-props-and-higher-order-components\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи замінять хуки рендер пропси та компоненти вищого порядку? </h3>\n<p>Часто рендер пропси та компоненти вищого порядку рендерять лише одного нащадка. Ми вважаємо, що хуки є простішим шляхом для того, щоб зробити це. Все ще ми можемо використовувати обидва шаблони (наприклад, віртуальний компонент скролінгу може мати проп <code class=\"gatsby-code-text\">renderItem</code> чи візуальний контейнер може мати власну структуру DOM). Але у більшості випадків, хуків буде достатньо для зменшення кількості вкладень у ващому дереві.</p>\n<h3 id=\"what-do-hooks-mean-for-popular-apis-like-redux-connect-and-react-router\"><a href=\"#what-do-hooks-mean-for-popular-apis-like-redux-connect-and-react-router\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Що означають хуки для популярних API, таких як Redux connect() чи React Router?</h3>\n<p>Ви можете використовувати ті ж самі API, що і завжди — вони продовжують працювати.</p>\n<p>React Redux, починаючи від версії 7.1.0, <a href=\"https://react-redux.js.org/api/hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">підтримує API хуків</a> і представляє хуки <code class=\"gatsby-code-text\">useDispatch</code> та <code class=\"gatsby-code-text\">useSelector</code>.</p>\n<p>React Router <a href=\"https://reacttraining.com/react-router/web/api/Hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">підтримує хуки</a>, починаючи від версії 5.1.</p>\n<p>Інші бібліотеки можливо будуть підтримувати хуки у майбутньому.</p>\n<h3 id=\"do-hooks-work-with-static-typing\"><a href=\"#do-hooks-work-with-static-typing\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи працюють хуки зі статичною типізацією? </h3>\n<p>Хуки були спроектовані з урахуванням статичної типізації. Оскільки вони є функціями, то їх легше правильно типізувати, аніж, скажімо, компоненти вищого порядку. Найновіші версії Flow і TypeScript для React вже включають підтримку хуків.</p>\n<p>Не менш важливо і те, що користувацькі хуки надають вам можливість накласти обмеження на React API, якщо вам потрібно типізувати їх більш строго певним чином. React надає вам примітиви, які ви можете комбінувати іншими способами, котрі ми передбачили у бібліотеці безпосередньо.</p>\n<h3 id=\"how-to-test-components-that-use-hooks\"><a href=\"#how-to-test-components-that-use-hooks\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як тестувати компоненти, які використовують хуки? </h3>\n<p>З точки зору React, компонент, що використовує хуки, є цілком звичайним компонентом. Якщо ваш спосіб тестування не покладається на деталі реалізації React, тестування компонентів з хуками не має відрізнятись від тестування будь-яких інших компонентів.</p>\n<blockquote>\n<p>Примітка</p>\n<p><a href=\"/docs/testing-recipes.html\">Рецепти тестування</a> має багато прикладів, які ви можете використати.</p>\n</blockquote>\n<p>Наприклад, ми маємо такий компонент лічильника:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Example</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    document<span class=\"token punctuation\">.</span>title <span class=\"token operator\">=</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">Ви натиснули </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>count<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\"> разів</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Ви натиснули </span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token plain-text\"> разів</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span> <span class=\"token attr-name\">onClick</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        Натисни мене\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Ми протестуємо його з використанням React DOM. Щоб впевнитись у тому, що поведінка співпадає з браузерною, ми обгорнемо код для рендерингу й оновлення у виклики <a href=\"/docs/test-utils.html#act\"><code class=\"gatsby-code-text\">ReactTestUtils.act()</code></a>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">import</span> React <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> ReactDOM <span class=\"token keyword\">from</span> <span class=\"token string\">'react-dom'</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> act <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react-dom/test-utils'</span><span class=\"token punctuation\">;</span></span><span class=\"token keyword\">import</span> Counter <span class=\"token keyword\">from</span> <span class=\"token string\">'./Counter'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">let</span> container<span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">beforeEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  container <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">createElement</span><span class=\"token punctuation\">(</span><span class=\"token string\">'div'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  document<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">.</span><span class=\"token function\">appendChild</span><span class=\"token punctuation\">(</span>container<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">afterEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  document<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">.</span><span class=\"token function\">removeChild</span><span class=\"token punctuation\">(</span>container<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  container <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'can render and update a counter'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// Тестуємо перший рендер і ефект</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    ReactDOM<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Counter</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> container<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token keyword\">const</span> button <span class=\"token operator\">=</span> container<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">'button'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> label <span class=\"token operator\">=</span> container<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">'p'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>label<span class=\"token punctuation\">.</span>textContent<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Ви натиснули 0 разів'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>document<span class=\"token punctuation\">.</span>title<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Ви натиснули 0 разів'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// Тестуємо другий рендер і ефект</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    button<span class=\"token punctuation\">.</span><span class=\"token function\">dispatchEvent</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">MouseEvent</span><span class=\"token punctuation\">(</span><span class=\"token string\">'click'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>bubbles<span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>label<span class=\"token punctuation\">.</span>textContent<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Ви натиснули 1 разів'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>document<span class=\"token punctuation\">.</span>title<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Ви натиснули 1 разів'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Виклики <code class=\"gatsby-code-text\">act()</code> також миттєво запустять вкладені в них ефекти.</p>\n<p>Якщо вам потрібно протестувати користувацький хук, ви можете зробити це, створивши компонент у вашому тесті і використати хук у ньому. Після цього ви можете протестувати щойно написаний компонент.</p>\n<p>Щоб зменшити об’єм шаблонного коду, ми рекомендуємо використовувати <a href=\"https://git.io/react-testing-library\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">react-testing-library</code></a>, яка спроектована з метою заохочення написання тестів, що використовують ваші компоненти так, як це будуть робити кінцеві користувачі.</p>\n<p>Для отримання додаткової інформації, дивіться <a href=\"/docs/testing-recipes.html\">Рецепти тестування</a>.</p>\n<h3 id=\"what-exactly-do-the-lint-rules-enforce\"><a href=\"#what-exactly-do-the-lint-rules-enforce\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Що саме перевіряють <a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">правила лінтера</a> у хуках? </h3>\n<p>Ми надаємо <a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">плагін для ESLint</a>, котрий змушує дотримуватись <a href=\"/docs/hooks-rules.html\">правил хуків</a> для уникнення помилок. Він припускає, що кожна функція, яка починається з ”<code class=\"gatsby-code-text\">use</code>” і великої літери після нього, є хуком. Ми розуміємо, що це припущення не ідеальне і може привести до хибних спрацювань, але без подібної домовленості на рівні екосистеми просто неможливо змусити хуки працювати коректно, а довші імена можуть завадити людям впроваджувати хуки або ж дотримуватись домовленості.</p>\n<p>У деталях правила вимагають, щоб:</p>\n<ul>\n<li>Виклики хуків знаходяться всередині <code class=\"gatsby-code-text\">PascalCase</code>-функції (тобто компонента) чи іншої <code class=\"gatsby-code-text\">useSomething</code> функції (тобто користувацького хука).</li>\n<li>Хуки викликаються в однаковому порядку при кожному рендері.</li>\n</ul>\n<p>Існує ще кілька правил, що можуть змінитись відповідно до того, як ми змінюємо правила для балансування між пошуком помилок і уникненням хибних спрацювань.</p>\n<h2 id=\"from-classes-to-hooks\"><a href=\"#from-classes-to-hooks\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Від класів до хуків </h2>\n<h3 id=\"how-do-lifecycle-methods-correspond-to-hooks\"><a href=\"#how-do-lifecycle-methods-correspond-to-hooks\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як методи життєвого циклу співвідносяться з хуками? </h3>\n<ul>\n<li><code class=\"gatsby-code-text\">constructor</code>: Функціональні компоненти не потребують конструктора. Ви можете ініціалізувати стан при виклику <a href=\"/docs/hooks-reference.html#usestate\"><code class=\"gatsby-code-text\">useState</code></a>. Якщо обчислення початкового стану є вартісною операцію, можна передати функцію до <code class=\"gatsby-code-text\">useState</code>.</li>\n<li><code class=\"gatsby-code-text\">getDerivedStateFromProps</code>: Натомість заплануйте оновлення <a href=\"#how-do-i-implement-getderivedstatefromprops\">при рендерингу</a>.</li>\n<li><code class=\"gatsby-code-text\">shouldComponentUpdate</code>: Зверніть увагу на <code class=\"gatsby-code-text\">React.memo</code> <a href=\"#how-do-i-implement-shouldcomponentupdate\">нижче</a>.</li>\n<li><code class=\"gatsby-code-text\">render</code>: Це тіло функціонального компонента.</li>\n<li><code class=\"gatsby-code-text\">componentDidMount</code>, <code class=\"gatsby-code-text\">componentDidUpdate</code>, <code class=\"gatsby-code-text\">componentWillUnmount</code>: Хук <a href=\"/docs/hooks-reference.html#useeffect\"><code class=\"gatsby-code-text\">useEffect</code></a> може замінити всі їхні комбінації (включно з <a href=\"#can-i-skip-an-effect-on-updates\">менш</a> <a href=\"#can-i-run-an-effect-only-on-updates\">частими</a> випадками).</li>\n<li><code class=\"gatsby-code-text\">getSnapshotBeforeUpdate</code>, <code class=\"gatsby-code-text\">componentDidCatch</code> і <code class=\"gatsby-code-text\">getDerivedStateFromError</code>: Поки що немає хуків, еквівалентних цим методам, але вони будуть додані найближчим часом.</li>\n</ul>\n<h3 id=\"how-can-i-do-data-fetching-with-hooks\"><a href=\"#how-can-i-do-data-fetching-with-hooks\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як я можу робити вибірку даних з допомогою хуків? </h3>\n<p>Ось <a href=\"https://codesandbox.io/s/jvvkoo8pq3\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">невелике демо</a>, що допоможе вам розпочати. Щоб дізнатися більше, ознайомтесь з <a href=\"https://www.robinwieruch.de/react-hooks-fetch-data/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">цією статтею</a> про вибірку даних з допомогою хуків.</p>\n<h3 id=\"is-there-something-like-instance-variables\"><a href=\"#is-there-something-like-instance-variables\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи є щось подібне до змінних екземпляра класу? </h3>\n<p>Так! Хук <a href=\"/docs/hooks-reference.html#useref\"><code class=\"gatsby-code-text\">useRef()</code></a> може використовуватись не лише для рефів DOM. Об’єкт “ref” є загальним контейнером, властивість <code class=\"gatsby-code-text\">current</code> якого, є змінною і може містити будь-яке значення, подібно до властивості екземпляра класу.</p>\n<p>Ви можете записати значення всередині <code class=\"gatsby-code-text\">useEffect</code>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Timer</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> intervalRef <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token comment\">// ...</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">    intervalRef<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> id<span class=\"token punctuation\">;</span></span>    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>intervalRef<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Якщо б ми лише хотіли встановити інтервал, реф був би непотрібний (<code class=\"gatsby-code-text\">id</code> може бути локальним для ефекту), але він міг бути корисним для очищення інтервалу з обробника події:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">  <span class=\"token comment\">// ...</span>\n  <span class=\"token keyword\">function</span> <span class=\"token function\">handleCancelClick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>intervalRef<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n  <span class=\"token comment\">// ...</span></code></pre></div>\n<p>У загальному випадку ви можете вважати рефи схожими на змінні екземпляра класу. Уникайте встановлення рефів під час рендерингу, якщо ви не реалізовуєте <a href=\"#how-to-create-expensive-objects-lazily\">ліниву ініціалізацію</a> — це може привести до неочікуваної поведінки. Як правило, ви захочете змінювати значення рефів у обробниках подій та ефектах.</p>\n<h3 id=\"should-i-use-one-or-many-state-variables\"><a href=\"#should-i-use-one-or-many-state-variables\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Скільки змінних стану мені слід використовувати — одну чи декілька? </h3>\n<p>Якщо ви звикли до класів, ви скоріш за все викликали <code class=\"gatsby-code-text\">useState()</code> один раз і зберігали весь стан в одному об’єкті. І якщо ви хочете, то ви можете так вчинити і з хуками. Ось приклад компонента, що слідує за рухами мишки. Ми зберігаємо його позицію і розмір у локальному стані:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Box</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>state<span class=\"token punctuation\">,</span> setState<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> left<span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> top<span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> width<span class=\"token operator\">:</span> <span class=\"token number\">100</span><span class=\"token punctuation\">,</span> height<span class=\"token operator\">:</span> <span class=\"token number\">100</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Скажімо, що ми хочемо написати деяку логіку, яка змінить значення <code class=\"gatsby-code-text\">left</code> і <code class=\"gatsby-code-text\">top</code>, коли користувач рухає мишкою. Зверніть увагу, що ми маємо об’єднувати ці поля з попереднім об’єктом стану вручну:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">  <span class=\"token comment\">// ...</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">handleWindowMouseMove</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token comment\">// Розпакування \"...state\" гарантує, що ми не \"втратимо\" width and height</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token operator\">...</span>state<span class=\"token punctuation\">,</span> left<span class=\"token operator\">:</span> e<span class=\"token punctuation\">.</span>pageX<span class=\"token punctuation\">,</span> top<span class=\"token operator\">:</span> e<span class=\"token punctuation\">.</span>pageY <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>    <span class=\"token punctuation\">}</span>\n    <span class=\"token comment\">// Примітка: ця реалізація дещо спрощена</span>\n    window<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">'mousemove'</span><span class=\"token punctuation\">,</span> handleWindowMouseMove<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> window<span class=\"token punctuation\">.</span><span class=\"token function\">removeEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">'mousemove'</span><span class=\"token punctuation\">,</span> handleWindowMouseMove<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">// ...</span></code></pre></div>\n<p>Об’єднання потрібне оскільки при оновленні змінної стану ми <em>замінюємо</em> її значення. Дана поведінка відрізняється від методу <code class=\"gatsby-code-text\">this.setState</code> у класі, який <em>об’єднує</em> оновлені поля в об’єкт.</p>\n<p>Якщо вам не вистачає автоматичного об’єднання, ви можете створити користувацький <code class=\"gatsby-code-text\">useLegacyState</code> хук, що об’єднує оновлення об’єкта стану. Проте <strong>ми радимо розділити стан на декілька змінних з урахуванням того, які значення скоріше за все будуть змінюватися разом.</strong></p>\n<p>Наприклад, ми могли розділити стан нашого компонента на об’єкти <code class=\"gatsby-code-text\">position</code> та <code class=\"gatsby-code-text\">size</code> і завжди замінювати <code class=\"gatsby-code-text\">position</code> без необхідності в об’єднанні:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Box</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>position<span class=\"token punctuation\">,</span> setPosition<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> left<span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> top<span class=\"token operator\">:</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>size<span class=\"token punctuation\">,</span> setSize<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> width<span class=\"token operator\">:</span> <span class=\"token number\">100</span><span class=\"token punctuation\">,</span> height<span class=\"token operator\">:</span> <span class=\"token number\">100</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">handleWindowMouseMove</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">setPosition</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> left<span class=\"token operator\">:</span> e<span class=\"token punctuation\">.</span>pageX<span class=\"token punctuation\">,</span> top<span class=\"token operator\">:</span> e<span class=\"token punctuation\">.</span>pageY <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>    <span class=\"token punctuation\">}</span>\n    <span class=\"token comment\">// ...</span></code></pre></div>\n<p>Крім того, розділення стану на незалежні змінні має ще одну перевагу. Це допоможе легко виокремити спільну логіку у користувацький хук пізніше, наприклад:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Box</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> position <span class=\"token operator\">=</span> <span class=\"token function\">useWindowPosition</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>size<span class=\"token punctuation\">,</span> setSize<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> width<span class=\"token operator\">:</span> <span class=\"token number\">100</span><span class=\"token punctuation\">,</span> height<span class=\"token operator\">:</span> <span class=\"token number\">100</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">function</span> <span class=\"token function\">useWindowPosition</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span>  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>position<span class=\"token punctuation\">,</span> setPosition<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> left<span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> top<span class=\"token operator\">:</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// ...</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> position<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Зверніть увагу на те, як ми змогли винести виклик <code class=\"gatsby-code-text\">useState</code> для змінної стану <code class=\"gatsby-code-text\">position</code> і відповідний ефект у користувацький хук без зміни їхнього коду. Якби весь стан був одним об’єктом, то зробити це було б значно складніше.</p>\n<p>Чи зерігаєте ви весь стан з використанням одного виклику <code class=\"gatsby-code-text\">useState</code>, чи викликаєте <code class=\"gatsby-code-text\">useState</code> для кожного поля окремо — обидва підходи будуть працювати. Але компоненти буде легше читати, якщо ви знайдете баланс між підходами і будете групувати пов’язані між собою змінні стану. Якщо логіка стану стає складною, ми радимо <a href=\"/docs/hooks-reference.html#usereducer\">керувати нею з допомогою редюсера</a> чи користувацького хука.</p>\n<h3 id=\"can-i-run-an-effect-only-on-updates\"><a href=\"#can-i-run-an-effect-only-on-updates\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи можна запускати ефект лише при оновленні? </h3>\n<p>Це доволі нечастий випадок. Якщо вам це потрібно, ви можете <a href=\"#is-there-something-like-instance-variables\">використати змінний реф</a>, щоб вручну зберегти логічне значення, що вказує на те чи відбувся, а потім перевірити його значення у вашому ефекті. (Якщо вам потрібно робити це часто, можете створити для цього користувацький хук.)</p>\n<h3 id=\"how-to-get-the-previous-props-or-state\"><a href=\"#how-to-get-the-previous-props-or-state\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як отримати попередні пропси чи стан? </h3>\n<p>Наразі ви можете зробити це вручну, <a href=\"#is-there-something-like-instance-variables\">використавши реф</a>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">const</span> prevCountRef <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    prevCountRef<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> count<span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> prevCount <span class=\"token operator\">=</span> prevCountRef<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Зараз: </span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token plain-text\">, а до цього: </span><span class=\"token punctuation\">{</span>prevCount<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Це може виглядати дещо ускладненим, але ви можете виокремити логіку в користувацький хук:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> prevCount <span class=\"token operator\">=</span> <span class=\"token function\">usePrevious</span><span class=\"token punctuation\">(</span>count<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Зараз: </span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token plain-text\">, а до цього: </span><span class=\"token punctuation\">{</span>prevCount<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">function</span> <span class=\"token function\">usePrevious</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">value</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span>  <span class=\"token keyword\">const</span> ref <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    ref<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> value<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> ref<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Зверніть увагу, що це спрацює для пропсів, стану чи будь-якого іншого обчисленого значення.</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">const</span> calculation <span class=\"token operator\">=</span> count <span class=\"token operator\">+</span> <span class=\"token number\">100</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> prevCalculation <span class=\"token operator\">=</span> <span class=\"token function\">usePrevious</span><span class=\"token punctuation\">(</span>calculation<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token comment\">// ...</span></code></pre></div>\n<p>Цілком можливо, що у майбутньому у React буде реалізовано хук <code class=\"gatsby-code-text\">usePrevious</code>, оскільки це потрібно відносно часто.</p>\n<p>Також дивіться <a href=\"#how-do-i-implement-getderivedstatefromprops\">рекомендований шаблон для похідного стану</a>.</p>\n<h3 id=\"why-am-i-seeing-stale-props-or-state-inside-my-function\"><a href=\"#why-am-i-seeing-stale-props-or-state-inside-my-function\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чому я бачу застарілі значення пропсів чи стану всередині моєї функції? </h3>\n<p>Кожна функція в компоненті, включно з обробниками подій та ефектами, “бачить” значення пропсів та стану того рендеру, під час якого вони були створені. Наприклад, розглянемо такий код:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Example</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">handleAlertClick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setTimeout</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Ви натиснули на: '</span> <span class=\"token operator\">+</span> count<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Ви натиснули </span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token plain-text\"> раз</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span> <span class=\"token attr-name\">onClick</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        Натисни на мене\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span> <span class=\"token attr-name\">onClick</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>handleAlertClick<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        Показати попередження\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Якщо ви спочатку натиснента “Показати попередженняt”, а потім інкрементуєте лічильник, попередження покаже значення змінної <code class=\"gatsby-code-text\">count</code> <strong>на момент натискання кнопки “Показати попередження”</strong>. Це виключає помилки в коді, що припускає незмінність стану чи пропсів.</p>\n<p>Якщо ви навмисно хочете зчитати <em>найновіший</em> стан з деякої асинхронної функції зворотнього виклику, ви можете зберегти його в <a href=\"/docs/hooks-faq.html#is-there-something-like-instance-variables\">рефі</a>, змінити його і прочитати його значення.</p>\n<p>Окрім цього, іншою можливою причиною того, що ви бачите застарілі пропси чи стан можуть бути неправильно вказані значення залежностей при використанні оптимізації за допомогою “масиву залежностей”. Наприклад, в ефекті другим аргументом вказано значення <code class=\"gatsby-code-text\">[]</code>, але при цьому він зчитує значення <code class=\"gatsby-code-text\">someProp</code>, він продовжить “бачити” початкове значення <code class=\"gatsby-code-text\">someProp</code>. Рішенням може бути вказання правильного масиву залежностей або відмова від нього взагалі. Ось тут можна дізнатись <a href=\"#is-it-safe-to-omit-functions-from-the-list-of-dependencies\">як вести себе з функціями</a>, а тут <a href=\"#what-can-i-do-if-my-effect-dependencies-change-too-often\">інші відомі способи</a> зниження частоти запуску ефектів без пропускання передачі залежностей.</p>\n<blockquote>\n<p>Примітка</p>\n<p>Ми надаємо правило <a href=\"https://github.com/facebook/react/issues/14920\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">exhaustive-deps</code></a>, як частину нашого пакунку <a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks#installation\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">eslint-plugin-react-hooks</code></a>. Воно попереджує про те, що залежності вказані невірно і пропонує рішення.</p>\n</blockquote>\n<h3 id=\"how-do-i-implement-getderivedstatefromprops\"><a href=\"#how-do-i-implement-getderivedstatefromprops\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як я можу реалізувати <code class=\"gatsby-code-text\">getDerivedStateFromProps</code>? </h3>\n<p>Незважаючи на те, що скоріш за все <a href=\"/blog/2018/06/07/you-probably-dont-need-derived-state.html\">він вам не потрібен</a>, у випадку потреби (наприклад реалізації компонента <code class=\"gatsby-code-text\">&lt;Transition&gt;</code>), ви можете оновити стан прямо під час рендерингу. React негайно зробить повторний рендер компонента з оновленим станом після виходу з першого рендеру без особливих накладних витрат.</p>\n<p>У наступному прикладі ми зберігаємо попереднє значення пропу <code class=\"gatsby-code-text\">row</code> у змінній стану для порівняння:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">ScrollView</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span>row<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>isScrollingDown<span class=\"token punctuation\">,</span> setIsScrollingDown<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>prevRow<span class=\"token punctuation\">,</span> setPrevRow<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>row <span class=\"token operator\">!==</span> prevRow<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Row змінився після останнього рендеру. Оновлюємо isScrollingDown.</span>\n    <span class=\"token function\">setIsScrollingDown</span><span class=\"token punctuation\">(</span>prevRow <span class=\"token operator\">!==</span> <span class=\"token keyword\">null</span> <span class=\"token operator\">&amp;&amp;</span> row <span class=\"token operator\">></span> prevRow<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">setPrevRow</span><span class=\"token punctuation\">(</span>row<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">Гортаємо вниз: </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>isScrollingDown<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Спочатку це може виглядати дивно, але оновлення під час рендеру це, по суті, і є те чим завжди концептуально був <code class=\"gatsby-code-text\">getDerivedStateFromProps</code>.</p>\n<h3 id=\"is-there-something-like-forceupdate\"><a href=\"#is-there-something-like-forceupdate\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи є щось схоже на forceUpdate? </h3>\n<p>Хуки <code class=\"gatsby-code-text\">useState</code> та <code class=\"gatsby-code-text\">useReducer</code> <a href=\"/docs/hooks-reference.html#bailing-out-of-a-state-update\">припиняють оновлення</a> якщо наступне значення дорівнює попередньому. Зміна стану на місці і виклик <code class=\"gatsby-code-text\">setState</code> не спричинять повторного рендеру.</p>\n<p>Як правило, ви не повинні змінювати локальний стан у React. Проте, у якості запасного виходу, ви можете використати збільшення лічильника, щоб спричинити повторний рендер, навіть якщо стан не змінився:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>ignored<span class=\"token punctuation\">,</span> forceUpdate<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useReducer</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">x</span> <span class=\"token operator\">=></span> x <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">handleClick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">forceUpdate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span></code></pre></div>\n<p>По можливості намагайтесь уникати такого підходу.</p>\n<h3 id=\"can-i-make-a-ref-to-a-function-component\"><a href=\"#can-i-make-a-ref-to-a-function-component\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи можу я зробити реф на функціональний компонент? </h3>\n<p>Хоча це і не потрібно надто часто, ви можете надати деякі імперативні методи батьківському компоненту, використавши хук <a href=\"/docs/hooks-reference.html#useimperativehandle\"><code class=\"gatsby-code-text\">useImperativeHandle</code></a>.</p>\n<h3 id=\"how-can-i-measure-a-dom-node\"><a href=\"#how-can-i-measure-a-dom-node\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як я можу обмежити вузол DOM? </h3>\n<p>Один рудиментарний спосіб для виміру положення чи розміру вузла DOM, ви можете використати <a href=\"/docs/refs-and-the-dom.html#callback-refs\">реф зворотнього виклику</a>. React викличе функцію зворотнього виклику кожного разу, коли реф прикріплюється до іншого вузла. Ось <a href=\"https://codesandbox.io/s/l7m0v5x4v9\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">невеличка демонстрація</a>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">MeasureExample</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>height<span class=\"token punctuation\">,</span> setHeight<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> measuredRef <span class=\"token operator\">=</span> <span class=\"token function\">useCallback</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">node</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>node <span class=\"token operator\">!==</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">setHeight</span><span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">.</span><span class=\"token function\">getBoundingClientRect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>height<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span> <span class=\"token attr-name\">ref</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>measuredRef<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Hello, world</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h2</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Заголовок вище має висоту </span><span class=\"token punctuation\">{</span>Math<span class=\"token punctuation\">.</span><span class=\"token function\">round</span><span class=\"token punctuation\">(</span>height<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span><span class=\"token plain-text\"> пікселів</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h2</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>У цьому прикладі ми не використали <code class=\"gatsby-code-text\">useRef</code>, оскільки об’єкт рефу не повідомляє нас про <em>зміни</em> поточного значення рефу. Використання рефу зворотнього виклику гарантує, що <a href=\"https://codesandbox.io/s/818zzk8m78\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">навіть якщо дочірній компонент відображає обмежений вузол пізніше</a> (наприклад, у відповідь на натискання), ми все рівно отримаємо повідомлення про це у батьківському компоненті і зможемо оновити обмеження.</p>\n<p>Зверніть увагу на передачу <code class=\"gatsby-code-text\">[]</code> у якості масива залежностей <code class=\"gatsby-code-text\">useCallback</code>. Вона гарантує, що наш реф зворотнього виклику не зміниться між повторними рендерами, а отже React не буде викликати його без необхідності.</p>\n<p>Також, реф зворотнього виклику буде викликано лише коли компоненту монтується та демонтується, так як відрендерений <code class=\"gatsby-code-text\">&lt;h1&gt;</code> компонент залишається присутнім протягом всіх ререндерів.  Якщо ви хочете отримувати повідомлення, коли компонент змінює розмір, ви можете скористатися <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">ResizeObserver</code></a> або користувацьким хуком.</p>\n<p>За бажанням можна <a href=\"https://codesandbox.io/s/m5o42082xy\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">виокремити цю логіку</a> у повторно використовуваний хук:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">MeasureExample</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>rect<span class=\"token punctuation\">,</span> ref<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useClientRect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span> <span class=\"token attr-name\">ref</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>ref<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Hello, world</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token punctuation\">{</span>rect <span class=\"token operator\">!==</span> <span class=\"token keyword\">null</span> <span class=\"token operator\">&amp;&amp;</span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h2</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Заголовок вище має висоту </span><span class=\"token punctuation\">{</span>Math<span class=\"token punctuation\">.</span><span class=\"token function\">round</span><span class=\"token punctuation\">(</span>rect<span class=\"token punctuation\">.</span>height<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span><span class=\"token plain-text\"> пікселів</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h2</span><span class=\"token punctuation\">></span></span>\n      <span class=\"token punctuation\">}</span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">useClientRect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>rect<span class=\"token punctuation\">,</span> setRect<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> ref <span class=\"token operator\">=</span> <span class=\"token function\">useCallback</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">node</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>node <span class=\"token operator\">!==</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">setRect</span><span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">.</span><span class=\"token function\">getBoundingClientRect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">[</span>rect<span class=\"token punctuation\">,</span> ref<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3 id=\"what-does-const-thing-setthing--usestate-mean\"><a href=\"#what-does-const-thing-setthing--usestate-mean\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Що означає const [thing, setThing] = useState()? </h3>\n<p>Якщо ви не знайомі з цим синтаксисом, прочитайте <a href=\"/docs/hooks-state.html#tip-what-do-square-brackets-mean\">пояснення</a> у документації для хука стану.</p>\n<h2 id=\"performance-optimizations\"><a href=\"#performance-optimizations\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Оптимізація продуктивності </h2>\n<h3 id=\"can-i-skip-an-effect-on-updates\"><a href=\"#can-i-skip-an-effect-on-updates\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи можу я пропустити ефект при оновленні? </h3>\n<p>Так. Дивіться <a href=\"/docs/hooks-reference.html#conditionally-firing-an-effect\">умовне спрацювання ефекту</a>. Зверніть увагу, якщо ви забудете обробити оновлення, то ви можете <a href=\"/docs/hooks-effect.html#explanation-why-effects-run-on-each-update\">спричинити помилки</a>. Саме тому це і не є поведінкою за замовчуванням.</p>\n<h3 id=\"is-it-safe-to-omit-functions-from-the-list-of-dependencies\"><a href=\"#is-it-safe-to-omit-functions-from-the-list-of-dependencies\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи безпечно не вказувати в списку залежностей функції? </h3>\n<p>У загальному випадку — ні.</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Example</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> someProp <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">function</span> <span class=\"token function\">doSomething</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>someProp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">doSomething</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 🔴 Це небезбечно (виклик `doSomething`, що використовує `someProp`)</span></span><span class=\"token punctuation\">}</span></code></pre></div>\n<p>Доволі складно запам’ятати які пропси чи стан використовуються функціями ззовні ефекту. Саме тому <strong>функції, що потрібні ефекту, оголошуються безпосередньо <em>в</em> ефекті.</strong> Так буде простіше побачити, від яких значень з області видимості компонента залежить ефект:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Example</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> someProp <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">doSomething</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>someProp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token function\">doSomething</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>someProp<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// ✅ OK (наш ефект використовує лише `someProp`)</span></span><span class=\"token punctuation\">}</span></code></pre></div>\n<p>Якщо після подібної зміни ми не використовуємо жодних значень з області видимості компонента, то ми можемо безпечно вказати <code class=\"gatsby-code-text\">[]</code>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">function</span> <span class=\"token function\">doSomething</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'hello'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">doSomething</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// ✅ OK у цьому прикладі, тому що ми не використовуємо *жодних* значень з області видимості компонента</span></span></code></pre></div>\n<p>Залежно від ваших потреб є ще кілька варіантів, описаних нижче.</p>\n<blockquote>\n<p>Примітка</p>\n<p>Ми надаємо правило <a href=\"https://github.com/facebook/react/issues/14920\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">exhaustive-deps</code></a>, як частину нашого пакунку <a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks#installation\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">eslint-plugin-react-hooks</code></a>. Воно допоможе знайти компоненти, які не оброблюють оновлення належним чином.</p>\n</blockquote>\n<p>Давайте глянемо, чому це важливо.</p>\n<p>Якщо ви вкажете <a href=\"/docs/hooks-reference.html#conditionally-firing-an-effect\">список залежностей</a> в якості останнього аргумента <code class=\"gatsby-code-text\">useEffect</code>, <code class=\"gatsby-code-text\">useLayoutEffect</code>, <code class=\"gatsby-code-text\">useMemo</code>, <code class=\"gatsby-code-text\">useCallback</code> чи <code class=\"gatsby-code-text\">useImperativeHandle</code>, він має містити всі значення, що використовуються у тілі функції зворотнього виклику та беруть участь у потоці даних React, включно з пропсами, станом і їх похідними.</p>\n<p>Можна безпечно пропустити функцію з списку залежностей <strong>лише</strong> тоді, коли вона (чи функції, які вона викликає) не посилається на пропси, стан чи їх похідні. У цьому прикладі є помилка:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">ProductPage</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> productId <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>product<span class=\"token punctuation\">,</span> setProduct<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">async</span> <span class=\"token keyword\">function</span> <span class=\"token function\">fetchProduct</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">'http://myapi/product/'</span> <span class=\"token operator\">+</span> productId<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Використовує проп productId</span></span>    <span class=\"token keyword\">const</span> json <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">setProduct</span><span class=\"token punctuation\">(</span>json<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">fetchProduct</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 🔴 Неправильно, тому що `fetchProduct` використовує `productId`</span></span>  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><strong>Рекомендується виправляти таку помилку, виконавши переміщення функції <em>всередину</em> вашого ефекту</strong>. Так буде простіше побачити, які пропси чи стан використовуються ефектом і впевнитись, що всі вони оголошені:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">ProductPage</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> productId <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>product<span class=\"token punctuation\">,</span> setProduct<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token comment\">// Перемістивши функцію всередину ефекту, ми можемо відразу помітити, які значення він використовує.</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">async</span> <span class=\"token keyword\">function</span> <span class=\"token function\">fetchProduct</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">'http://myapi/product/'</span> <span class=\"token operator\">+</span> productId<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">const</span> json <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">setProduct</span><span class=\"token punctuation\">(</span>json<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span></span>\n    <span class=\"token function\">fetchProduct</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>productId<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// ✅ Вірно, тому що наш ефект використовує лише productId</span></span>  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Крім того, це дозволяє вам обробляти невпорядковані відповіді, використавши локальну змінну всередині ефекту:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">let</span> ignore <span class=\"token operator\">=</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span></span>    <span class=\"token keyword\">async</span> <span class=\"token keyword\">function</span> <span class=\"token function\">fetchProduct</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">'http://myapi/product/'</span> <span class=\"token operator\">+</span> productId<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">const</span> json <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>ignore<span class=\"token punctuation\">)</span> <span class=\"token function\">setProduct</span><span class=\"token punctuation\">(</span>json<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token function\">fetchProduct</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span> ignore <span class=\"token operator\">=</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>productId<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Ми перемістили функцію в ефект, щоб не вказувати її в списку залежностей.</p>\n<blockquote>\n<p>Порада</p>\n<p>Перегляньте <a href=\"https://codesandbox.io/s/jvvkoo8pq3\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">це невеличке демо</a> і <a href=\"https://www.robinwieruch.de/react-hooks-fetch-data/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">цю статтю</a>, щоб дізнатися більше про вибірку даних з хуками.</p>\n</blockquote>\n<p><strong>Якщо ви з певних причин <em>не можете</em> перемістити функцію в ефект, є кілька інших варіантів:</strong></p>\n<ul>\n<li><strong>Ви можете спробувати винести функцію за межі вашого компонента</strong>. У цьому випадку, функція гарантовано не буде посилатись на пропси чи стан, тому її можна не вказувати у списку залежностей.</li>\n<li>Якщо функція, яку ви викликаєте, є чистим обчисленням і її можна безпечно викликати під час рендерингу, то ви можете <strong>викликати її поза межами ефекту</strong> і зробити ефект залежним від повернутого значення.</li>\n<li>У крайньому випадку, ви можете <strong>додати функцію до залежностей ефекту, але при цьому <em>обгорнути її визначення</em></strong> у хук <a href=\"/docs/hooks-reference.html#usecallback\"><code class=\"gatsby-code-text\">useCallback</code></a>. Це гарантує її незмінність при кожному рендері, допоки не зміняться <em>її власні</em> залежності:</li>\n</ul>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">ProductPage</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> productId <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token comment\">// ✅ Обгортаємо в useCallback, щоб запобігти зміни при кожному рендері</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> fetchProduct <span class=\"token operator\">=</span> <span class=\"token function\">useCallback</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token comment\">// ... Робимо щось з productId ...</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>productId<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// ✅ Перераховуємо всі залежності useCallback</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">ProductDetails</span></span> <span class=\"token attr-name\">fetchProduct</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>fetchProduct<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">ProductDetails</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> fetchProduct <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">fetchProduct</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>fetchProduct<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// ✅ Усі залежності useEffect вказані</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Зверніть увагу, що у прикладі вище, ми <strong>повинні</strong> вказати функцію у списку залежностей. Це гарантує, що зміна пропу <code class=\"gatsby-code-text\">productId</code> компонента <code class=\"gatsby-code-text\">ProductPage</code> автоматично запустить повторну вибірку даних у компоненті <code class=\"gatsby-code-text\">ProductDetails</code>.</p>\n<h3 id=\"what-can-i-do-if-my-effect-dependencies-change-too-often\"><a href=\"#what-can-i-do-if-my-effect-dependencies-change-too-often\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Що я можу зробити, якщо залежності мого ефекту змінюються надто часто? </h3>\n<p>Часом ваш ефект може залежати від стану, що змінюється занадто часто. У вас може виникнути бажання пропустити цей стан із списку залежностей, але зазвичай це приводить до помилок:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Цей ефект залежить від стану `count`</span></span>    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 🔴 Помилка: змінна `count` не вказана як залежність</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Порожній набір залежностей <code class=\"gatsby-code-text\">[]</code> означає, що ефект буде виконуватися тільки один раз коли компонент монтується, а не на кожну повторну візуалізацію. Проблема полягає в тому, що всередині функції зворотнього виклику <code class=\"gatsby-code-text\">setInterval</code>, значення<code class=\"gatsby-code-text\">count</code> не змінюється, тому що ми створили замикання зі значенням <code class=\"gatsby-code-text\">count</code>, встановленим на<code class=\"gatsby-code-text\">0</code>, як це було при запуску ефекту callback. Кожну секунду ця функція зворотнього виклику потім викликає <code class=\"gatsby-code-text\">setCount (0 + 1)</code>, тому кількість ніколи не перевищує 1.</p>\n<p>Вказання <code class=\"gatsby-code-text\">[count]</code> у якості списка залежностей виправить помилку, але спричинить скидання інтервалу на кожному оновленні. Фактично, кожен <code class=\"gatsby-code-text\">setInterval</code> отримав би шанс бути виконаним перед очищенням (подібно до <code class=\"gatsby-code-text\">setTimeout</code>.) Така поведінка може бути небажаною. Щоб виправити це, ми можемо використати <a href=\"/docs/hooks-reference.html#functional-updates\">функціональну форму оновлення <code class=\"gatsby-code-text\">setState</code></a>. Вона дозволить нам вказати <em>як</em> стан має змінитись, при цьому не посилаючись на <em>поточний</em> стан:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">c</span> <span class=\"token operator\">=></span> c <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// ✅ Цей рядок не залежить від змінної `count` ззовні</span></span>    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// ✅ Наш ефект не використовує жодних змінних в області видимості компонента</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>(Ідентичність функції <code class=\"gatsby-code-text\">setCount</code> гарантована, а тому її можна безпечно пропустити.)</p>\n<p>Тепер функція зворотнього виклику <code class=\"gatsby-code-text\">setInterval</code> виконується раз на секунду, але кожен раз, коли внутрішній виклик<code class=\"gatsby-code-text\">setCount</code> може використовувати оновлене значення для <code class=\"gatsby-code-text\">count</code> (що називається <code class=\"gatsby-code-text\">c</code> у зворотному виклику).</p>\n<p>У більш складних випадках (наприклад, коли стан залежить від іншого стану), спробуйте винести логіку оновлення стану з ефекта, використавши <a href=\"/docs/hooks-reference.html#usereducer\">хук <code class=\"gatsby-code-text\">useReducer</code></a>. <a href=\"https://adamrackis.dev/state-and-use-reducer/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Ця стаття</a> пропопонує приклад того, як це можна зробити. <strong>Ідентичність функції <code class=\"gatsby-code-text\">dispatch</code>, хука <code class=\"gatsby-code-text\">useReducer</code>, завжди незмінна</strong> — навіть якщо функція-редюсер оголошена всередині компонента і читає його пропси.</p>\n<p>У крайньому випадку, якщо ви хочете щось схоже на <code class=\"gatsby-code-text\">this</code> у класі, ви можете <a href=\"/docs/hooks-faq.html#is-there-something-like-instance-variables\">використати реф</a> для збереження змінної, яку ви можете зчитувати і перезаписувати. Наприклад:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Example</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token comment\">// Зберегти останні пропси у рефі.</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> latestProps <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    latestProps<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> props<span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">tick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token comment\">// Прочитати останні пропси у будь-який момент</span></span><span class=\"gatsby-highlight-code-line\">      console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>latestProps<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">const</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span>tick<span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Цей ефект ніколи не буде запущено повторно</span></span><span class=\"token punctuation\">}</span></code></pre></div>\n<p>Робіть так лише якщо ви не можете знайти кращої альтернативи, тому що поведінка компонентів, яка покладається на змінність, є менш передбачуваною. Якщо існує якийсь шаблон, який ви не можете гарно виразити, <a href=\"https://github.com/facebook/react/issues/new\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">відкрийте проблему</a> з прикладом виконуваного коду і ми постараємося вам допомогти.</p>\n<h3 id=\"how-do-i-implement-shouldcomponentupdate\"><a href=\"#how-do-i-implement-shouldcomponentupdate\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як я можу реалізувати shouldComponentUpdate? </h3>\n<p>Ви можете обгорнути функціональний компонент у виклик <code class=\"gatsby-code-text\">React.memo</code>, щоб поверхнево порівняти його пропси:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">const</span> Button <span class=\"token operator\">=</span> React<span class=\"token punctuation\">.</span><span class=\"token function\">memo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// ваш компонент</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Це не є хуком, тому що ця функція не веде себе як хук. <code class=\"gatsby-code-text\">React.memo</code> є еквівалентом <code class=\"gatsby-code-text\">PureComponent</code>, але вона порівнює тільки пропси. (Ви також можете передати другий аргумент, щоб вказати власну функцію порівняння, яка приймає старі і нові пропси. Якщо вона повертає true, оновлення не відбудеться.)</p>\n<p><code class=\"gatsby-code-text\">React.memo</code> не порівнює стан, тому що не існує єдиного об’єкта стану, який би можна було б порівняти. Але ви також можете зробити дочірні компоненти чистими чи навіть <a href=\"/docs/hooks-faq.html#how-to-memoize-calculations\">оптимізувати їх вибірково, використавши хук <code class=\"gatsby-code-text\">useMemo</code></a>.</p>\n<h3 id=\"how-to-memoize-calculations\"><a href=\"#how-to-memoize-calculations\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як запам’ятати обчислення? </h3>\n<p>Хук <a href=\"/docs/hooks-reference.html#usememo\"><code class=\"gatsby-code-text\">useMemo</code></a> дозволяє вам закешувати обчислення між кількома рендерами, “запам’ятавши” попереднє обчислення:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">const</span> memoizedValue <span class=\"token operator\">=</span> <span class=\"token function\">useMemo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">computeExpensiveValue</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Цей код викликає <code class=\"gatsby-code-text\">computeExpensiveValue(a, b)</code>. Але якщо залежності <code class=\"gatsby-code-text\">[a, b]</code> не змінились у порівнянні з їх попередніми значеннями, <code class=\"gatsby-code-text\">useMemo</code> пропустить повторний виклик і просто перевикористає останнє повернуте значення.</p>\n<p>Пам’ятайте, що функція, передана до <code class=\"gatsby-code-text\">useMemo</code>, запускається під час рендерингу. Не робіть у ній нічого, що ви зазвичай не робите під час рендерингу. Наприклад, побічні ефекти мають бути в <code class=\"gatsby-code-text\">useEffect</code>, а не <code class=\"gatsby-code-text\">useMemo</code>.</p>\n<p><strong>Ви можете покластись на <code class=\"gatsby-code-text\">useMemo</code> як на оптимізацію продуктивності, а не на семантичу гарантію.</strong> У майбутньому React може вирішити “забути” деякі попередньо мемоізовані значення і переобчислити їх при наступному рендері, наприклад, для звільнення пам’яті для компонентів поза областю видимості екрана. Напишіть ваш код так, щоб він працював без <code class=\"gatsby-code-text\">useMemo</code>, а потім додайте його для оптимізації продуктивності. (У нечастих випадках, коли значення <em>ніколи</em> не обчислюється повторно, ви можете <a href=\"#how-to-create-expensive-objects-lazily\">ліниво ініціалізувати</a> реф.)</p>\n<p>Зручно також те, що <code class=\"gatsby-code-text\">useMemo</code> дає можливість пропускати вартісний повторний рендер потомків:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Parent</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> a<span class=\"token punctuation\">,</span> b <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// Повторно рендериться при зміні `a`:</span>\n  <span class=\"token keyword\">const</span> child1 <span class=\"token operator\">=</span> <span class=\"token function\">useMemo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Child1</span></span> <span class=\"token attr-name\">a</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>a<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>a<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">// Повторно рендериться при зміні `b`:</span>\n  <span class=\"token keyword\">const</span> child2 <span class=\"token operator\">=</span> <span class=\"token function\">useMemo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Child2</span></span> <span class=\"token attr-name\">b</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>b<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>b<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token punctuation\">{</span>child1<span class=\"token punctuation\">}</span><span class=\"token plain-text\">\n      </span><span class=\"token punctuation\">{</span>child2<span class=\"token punctuation\">}</span><span class=\"token plain-text\">\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Зверніть увагу, що цей підхід не спрацює у циклі, тому що виклики хуків <a href=\"/docs/hooks-rules.html\">не можна</a> помістити в цикл. Але ви можете виокремити компонент для елемента списку і викликати <code class=\"gatsby-code-text\">useMemo</code> там.</p>\n<h3 id=\"how-to-create-expensive-objects-lazily\"><a href=\"#how-to-create-expensive-objects-lazily\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як ліниво обчислити вартісні об’єкти? </h3>\n<p><code class=\"gatsby-code-text\">useMemo</code> дозволяє <a href=\"#how-to-memoize-calculations\">запам’ятати вартісне обчислення</a> для однакових залежностей. Проте він відіграє лише роль підказки для React і <em>не гарантує</em>, що повторні обчислення не будуть виконані знову. Але часом ви маєте бути впевнені, що об’єкт був створений лише раз.</p>\n<p><strong>Першим поширеним випадком є вартісне створення початкового стану:</strong></p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Table</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// ⚠️ createRows() викликається при кожному рендері</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>rows<span class=\"token punctuation\">,</span> setRows<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token function\">createRows</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>count<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Щоб запобігти повторному створенню початкового стану, ми можемо передати <strong>функцію</strong> до <code class=\"gatsby-code-text\">useState</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Table</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// ✅ createRows() буде викликана лише раз</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>rows<span class=\"token punctuation\">,</span> setRows<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">createRows</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>count<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>React викличе цю функцію лише під час першого рендеру. Перегляньте <a href=\"/docs/hooks-reference.html#usestate\">API-довідник для хука <code class=\"gatsby-code-text\">useState</code></a>.</p>\n<p><strong>Іноді ви можете захотіти уникнути повторного створення початкового значення <code class=\"gatsby-code-text\">useRef()</code>.</strong> Наприклад, ви хочете впевнитись, що екземпляр деякого імперативного класу буде створений лише раз:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Image</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// ⚠️ IntersectionObserver створюється при кожному рендері</span>\n  <span class=\"token keyword\">const</span> ref <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">IntersectionObserver</span><span class=\"token punctuation\">(</span>onIntersect<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"gatsby-code-text\">useRef</code> <strong>не</strong> реалізує перевантаження, що дозволяє приймати особливу функцію як <code class=\"gatsby-code-text\">useState</code>. Замість цього ви можете написати вашу власну функцію, що ліниво створить і ініціалізує його значення:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Image</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> ref <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// ✅ IntersectionObserver ліниво створюється один раз</span>\n  <span class=\"token keyword\">function</span> <span class=\"token function\">getObserver</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>ref<span class=\"token punctuation\">.</span>current <span class=\"token operator\">===</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      ref<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">IntersectionObserver</span><span class=\"token punctuation\">(</span>onIntersect<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> ref<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token comment\">// Викличіть getObserver() за потреби</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Такий варіант дозволить уникнути створення вартісного об’єкта до моменту, коли він дійсно потрібен вперше. Якщо ви використовуєте Flow чи TypeScript, ви також можете встановити ненульовий <code class=\"gatsby-code-text\">getObserver()</code> тип для зручності.</p>\n<h3 id=\"are-hooks-slow-because-of-creating-functions-in-render\"><a href=\"#are-hooks-slow-because-of-creating-functions-in-render\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Чи є хуки повільними через створення функцій при рендері? </h3>\n<p>Ні. У сучасних браузерах сира продуктивність замикань не надто відрізняється від класів, крім деяких особливих випадків.</p>\n<p>Також враховуйте, що реалізація хуків більш ефективна у кількох напрямках:</p>\n<ul>\n<li>Хуки не роблять зайвої роботи, що потрібна класам, наприклад, створення екземплярів класу і прив’язка обробників події у конструкторі.</li>\n<li><strong>Характерний код з використанням хуків не потребує глибокого дерева компонентів</strong>, що є поширених у кодових базах з використаням компонентів вищого порядку, рендер пропсів та контексту. React матиме менше роботи з меншими деревами компонентів.</li>\n</ul>\n<p>Традиційно, проблеми продуктивності вбудованих функцій у React були пов’язані з тим, як передача нових функцій зворотнього виклику при кожному рендері порушує оптимізації <code class=\"gatsby-code-text\">shouldComponentUpdate</code> у дочірніх компонентах. Хуки підходять до цієї проблеми з трьох сторін.</p>\n<ul>\n<li>\n<p>Хук <a href=\"/docs/hooks-reference.html#usecallback\"><code class=\"gatsby-code-text\">useCallback</code></a> дозволяє вам зберегти посилання на ту саму функцію зворотнього виклику між повторними рендерами, а тому <code class=\"gatsby-code-text\">shouldComponentUpdate</code> продовжить коректно працювати:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token comment\">// Зміниться лише при зміні `a` чи `b`</span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">const</span> memoizedCallback <span class=\"token operator\">=</span> <span class=\"token function\">useCallback</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span>  <span class=\"token function\">doSomething</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n</li>\n<li>Використання <a href=\"/docs/hooks-faq.html#how-to-memoize-calculations\">хука <code class=\"gatsby-code-text\">useMemo</code></a> полегшує контроль оновлення індивідуальних потомків, зменшуючи потребу в чистих компонентах.</li>\n<li>Нарешті, <a href=\"/docs/hooks-reference.html#usereducer\">хук <code class=\"gatsby-code-text\">useReducer</code></a> зменшує потребу глибокої передачі функцій зворотнього виклику, як пояснюється нижче.</li>\n</ul>\n<h3 id=\"how-to-avoid-passing-callbacks-down\"><a href=\"#how-to-avoid-passing-callbacks-down\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як уникнути передачі функцій зворотнього виклику вниз? </h3>\n<p>Ми зрозуміли, що більшості людей не подобається вручну передавати функції зворотнього виклику вниз на кожному рівні дерева компонентів. Незважаючи на те, що це виглядає більш явно, це може здатись надзвичайно громіздким.</p>\n<p>У великих деревах компонентів у якості альтернативи ми радимо передавати функцію <code class=\"gatsby-code-text\">dispatch</code> хука <a href=\"/docs/hooks-reference.html#usereducer\"><code class=\"gatsby-code-text\">useReducer</code></a> через контекст:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">const</span> TodosDispatch <span class=\"token operator\">=</span> React<span class=\"token punctuation\">.</span><span class=\"token function\">createContext</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">TodosApp</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token comment\">// Примітка: `dispatch` не змінюється при повторних рендерах</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>todos<span class=\"token punctuation\">,</span> dispatch<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useReducer</span><span class=\"token punctuation\">(</span>todosReducer<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">TodosDispatch.Provider</span></span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>dispatch<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">DeepTree</span></span> <span class=\"token attr-name\">todos</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>todos<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token class-name\">TodosDispatch.Provider</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Будь-який потомок у дереві всередині <code class=\"gatsby-code-text\">TodosApp</code> може використовувати функцію <code class=\"gatsby-code-text\">dispatch</code>, щоб передати дії вверх до <code class=\"gatsby-code-text\">TodosApp</code>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">DeepChild</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token comment\">// Якщо ми хочемо виконати дію, ми можемо отримати dispatch з контексту.</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> dispatch <span class=\"token operator\">=</span> <span class=\"token function\">useContext</span><span class=\"token punctuation\">(</span>TodosDispatch<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">function</span> <span class=\"token function\">handleClick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">dispatch</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> type<span class=\"token operator\">:</span> <span class=\"token string\">'add'</span><span class=\"token punctuation\">,</span> text<span class=\"token operator\">:</span> <span class=\"token string\">'привіт'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span> <span class=\"token attr-name\">onClick</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>handleClick<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Додати завдання</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Цей варіант зручніше як з точки зору підтримки коду (немає потреби у передачі зайвих функцій зворотнього виклику), так і вирішує проблему функцій зворотнього виклику в цілому. Передача <code class=\"gatsby-code-text\">dispatch</code> вниз, як у вищенаведеному прикладі, є рекомендованим шаблоном для глибоких оновлень.</p>\n<p>Зверніть увагу, що ви й досі вільні обирати чи передавати <em>стан</em> вниз у якості пропсів (більш явно) або ж у якості контексту (більш зручно для глибоких оновлень). Якщо ваш контекст також передає вниз стан, використовуйте два різних типи контексту, оскільки контекст <code class=\"gatsby-code-text\">dispatch</code> ніколи не змінюється, а отже компоненти, що зчитують його, не потребують повторного рендеру, якщо тільки вони не потребують контекст зі станом додатку.</p>\n<h3 id=\"how-to-read-an-often-changing-value-from-usecallback\"><a href=\"#how-to-read-an-often-changing-value-from-usecallback\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як прочитати часто змінюване значення з useCallback? </h3>\n<blockquote>\n<p>Примітка</p>\n<p>Ми радимо <a href=\"#how-to-avoid-passing-callbacks-down\">передавати <code class=\"gatsby-code-text\">dispatch</code> у контексті вниз</a>, а не окремих функцій зворотнього виклику в пропсах. Підхід нижче описаний лише для повноти і у якості запасного виходу.</p>\n<p>Також зверніть увагу, що цей шаблон може спричинити проблеми у <a href=\"/blog/2018/03/27/update-on-async-rendering.html\">конкурентному режимі</a>. Ми плануємо надати більш зручні альтернативи у майбутньому, але найбезпечнішим рішенням наразі — скасування функції зворотнього виклику при зміні хоча б одного значення від якого він залежить.</p>\n</blockquote>\n<p>У нечастих випадках вам може бути потрібно запам’ятати функцію зворотнього виклику, використавши <a href=\"/docs/hooks-reference.html#usecallback\"><code class=\"gatsby-code-text\">useCallback</code></a>, але запам’ятовування не спрацює як слід, тому що внутрішня функція повинна повторно створюватись надто часто. Якщо функція, яку ви запам’ятовуєте, є оброником події і не використовується під час рендерингу, то ви можете <a href=\"#is-there-something-like-instance-variables\">використати реф як змінну екземпляра</a> і зберегти у ньому останнє значення вручну:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Form</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>text<span class=\"token punctuation\">,</span> updateText<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">''</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> textRef <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    textRef<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> text<span class=\"token punctuation\">;</span> <span class=\"token comment\">// Записати значення у реф</span></span>  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">const</span> handleSubmit <span class=\"token operator\">=</span> <span class=\"token function\">useCallback</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> currentText <span class=\"token operator\">=</span> textRef<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">;</span> <span class=\"token comment\">// Прочитати значення рефу</span></span>    <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span>currentText<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>textRef<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Не створювати handleSubmit повторно, як би було у випадку з [text]</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>text<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token parameter\">e</span> <span class=\"token operator\">=></span> <span class=\"token function\">updateText</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">ExpensiveTree</span></span> <span class=\"token attr-name\">onSubmit</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>handleSubmit<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Це доволі заплутаний підхід, але він показує, що ви можете покластись на цю оптимізацію як на запасний вихід. Буде більш адекватно винести її у окремий хук:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Form</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>text<span class=\"token punctuation\">,</span> updateText<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">''</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">// Буде мемоізована навіть при зміні `text`:</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> handleSubmit <span class=\"token operator\">=</span> <span class=\"token function\">useEventCallback</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span>    <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span>text<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>text<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>text<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token parameter\">e</span> <span class=\"token operator\">=></span> <span class=\"token function\">updateText</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">ExpensiveTree</span></span> <span class=\"token attr-name\">onSubmit</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>handleSubmit<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">function</span> <span class=\"token function\">useEventCallback</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">fn<span class=\"token punctuation\">,</span> dependencies</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span>  <span class=\"token keyword\">const</span> ref <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Неможливо викликати обробник події під час рендерингу.'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    ref<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> fn<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>fn<span class=\"token punctuation\">,</span> <span class=\"token operator\">...</span>dependencies<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token function\">useCallback</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> fn <span class=\"token operator\">=</span> ref<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">fn</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>ref<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>У будь-якому випадку, ми <strong>не радимо використовувати цей підхід</strong> і показуємо його тут лише для повноти документації. Натомість, надайте перевагу <a href=\"#how-to-avoid-passing-callbacks-down\">уникненню передачі функцій зворотнього виклику глибоко вниз</a>.</p>\n<h2 id=\"under-the-hood\"><a href=\"#under-the-hood\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Деталі реалізації </h2>\n<h3 id=\"how-does-react-associate-hook-calls-with-components\"><a href=\"#how-does-react-associate-hook-calls-with-components\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Як React асоціює виклики хуків з компонентами? </h3>\n<p>React відслідковує, який компонент рендериться у даний момент. Завдяки <a href=\"/docs/hooks-rules.html\">правилам хуків</a> ми знаємо, що хуки можуть викликатись лише з React-компонентів (чи користувацьких хуків, які теж викликаються лише з React-компонентів).</p>\n<p>Існує внутрішній список “комірок пам’яті”, пов’язаних з кожним компонентом. Вони є звичайними об’єктами JavaScript у яких ми можемо зберегти певні дані. Коли ви викликаєте хук на зразок <code class=\"gatsby-code-text\">useState()</code>, він зчитує поточну комірку (чи ініціалізує її під час першого рендеру) і зсуває вказівник на наступну. Саме так різні виклики <code class=\"gatsby-code-text\">useState()</code> отримують незалежний локальний стан.</p>\n<h3 id=\"what-is-the-prior-art-for-hooks\"><a href=\"#what-is-the-prior-art-for-hooks\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Що лежить в основі дизайну хуків? </h3>\n<p>Хуки об’єднують у собі ідеї кількох різних концепцій:</p>\n<ul>\n<li>Наші старі експерименти з функціональними API у репозиторії <a href=\"https://github.com/reactjs/react-future/tree/master/07%20-%20Returning%20State\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">react-future</a>.</li>\n<li>Експерименти спільноти React з API рендер пропсів, включно з <a href=\"https://github.com/reactions/component\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Reactions Component</a> <a href=\"https://github.com/ryanflorence\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Раяна Флоренса (Ryan Florence)</a>.</li>\n<li>Пропозиція <a href=\"https://gist.github.com/trueadm/17beb64288e30192f3aa29cad0218067\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ключового слова <code class=\"gatsby-code-text\">adopt</code></a>, як синтаксичного цукру для рендер пропсів, запропонована <a href=\"https://github.com/trueadm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Домініком Ґенневеєм (Dominic Gannaway)</a>.</li>\n<li>Змінні стану і комірки стану в <a href=\"http://displayscript.org/introduction.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">DisplayScript</a>.</li>\n<li><a href=\"https://reasonml.github.io/reason-react/docs/en/state-actions-reducer.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Компоненти-редюсери</a> у ReasonReact.</li>\n<li><a href=\"http://reactivex.io/rxjs/class/es6/Subscription.js~Subscription.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Підписки</a> в Rx.</li>\n<li><a href=\"https://github.com/ocamllabs/ocaml-effects-tutorial#2-effectful-computations-in-a-pure-setting\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Алгебраїчні ефекти</a> в Multicore OCaml.</li>\n</ul>\n<p><a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Себастьян Маркбоге (Sebastian Markbåge)</a> запропонував початковий дизайн хуків, який удосконалили <a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Ендрю Кларк (Andrew Clark)</a>, <a href=\"https://github.com/sophiebits\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Софі Алперт (Sophie Alpert)</a>, <a href=\"https://github.com/trueadm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Домінік Ґенневей (Dominic Gannaway)</a> та інші члени команди React.</p>","frontmatter":{"title":"Хуки: FAQ","next":null,"prev":"hooks-reference.html"},"fields":{"path":"content/docs/hooks-faq.md","slug":"docs/hooks-faq.html"}}},"pageContext":{"slug":"docs/hooks-faq.html"}},"staticQueryHashes":[]}