{"componentChunkName":"component---src-templates-docs-js","path":"/docs/hooks-effect.html","result":{"data":{"markdownRemark":{"html":"<p><em>Хуки</em> — це новинка в React 16.8. Вони дозволяють вам використовувати стан та інші можливості React без написання класу.</p>\n<p><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=\"gatsby-highlight-code-line\"><span class=\"token keyword\">import</span> React<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useState<span class=\"token punctuation\">,</span> useEffect <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span></span>\n<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=\"gatsby-highlight-code-line\">  <span class=\"token comment\">// Подібно до componentDidMount та componentDidUpdate:</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\">    <span class=\"token comment\">// Оновлюємо заголовок документа, використовуючи API браузера</span></span><span class=\"gatsby-highlight-code-line\">    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\">You clicked </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\"> times</span><span class=\"token template-punctuation string\">`</span></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>\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\"></span>\n<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\">Ви натиснули </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\"></span>\n<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 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\"></span>\n<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>button</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>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>Цей фрагмент коду базується на <a href=\"/docs/hooks-state.html\">прикладі лічильника з попередньої сторінки</a>, але ми додали новий функціонал до неї: ми змінюємо заголовок документа на користувацьке повідомлення, яке містить кількість натискань.</p>\n<p>Побічними ефектами в React є завантаження даних, оформлення підписки і зміна вручну DOM в React-компонентах. Неважливо, називаєте чи ви ці операції “побічними ефектами” (або просто “ефектами”) чи ні, вам скоріше за всього доводилось використовувати їх в ваших компонентах раніше.</p>\n<blockquote>\n<p>Порада</p>\n<p>Якщо ви знайомі з класовими методами життєвого циклу React, то уявляйте хук <code class=\"gatsby-code-text\">useEffect</code>, як комбінацію <code class=\"gatsby-code-text\">componentDidMount</code>, <code class=\"gatsby-code-text\">componentDidUpdate</code> та <code class=\"gatsby-code-text\">componentWillUnmount</code>.</p>\n</blockquote>\n<p>Існують два види побічних ефектів в React-компонентах: ті, які потребують і ті, які не потребують скидання. Давайте розглянемо обидва приклади в деталях.</p>\n<h2 id=\"effects-without-cleanup\"><a href=\"#effects-without-cleanup\" 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<p>Інколи ми хочемо <strong>запустити додатковий код після того, як React оновив DOM.</strong> Мережеві запити, ручні DOM-мутації та логування є прикладами ефектів, які не потребують скидання. Це тому, що ми їх запускаємо і після цього відразу забуваємо про них, оскільки більше ніяких додаткових дій не потрібно. Давайте порівняємо, як класи та хуки дозволяють реалізовувати такі побічні ефекти.</p>\n<h3 id=\"example-using-classes\"><a href=\"#example-using-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>В класових React-компонентах метод <code class=\"gatsby-code-text\">render</code> не може викликати побічні ефекти сам по собі. Це нам не підходить для наших цілей, оскільки ми в основному хочемо викликати наші ефекти <em>після того</em>, як React оновив DOM.</p>\n<p>Ось чому в класах React ми викликаємо побічні ефекти в <code class=\"gatsby-code-text\">componentDidMount</code> та <code class=\"gatsby-code-text\">componentDidUpdate</code> методах життєвого циклу. Повертаючись до нашого прикладу, тут показаний лічильник, який реалізований з допомогою класового React-компонента, який оновлює заголовок документа якраз після того, як React внесе зміни до DOM:</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\">class</span> <span class=\"token class-name\">Example</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</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\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n      count<span class=\"token operator\">:</span> <span class=\"token number\">0</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 function\">componentDidMount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    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><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token 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></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\"></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">componentDidUpdate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    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><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token 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></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span>\n  <span class=\"token function\">render</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>\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\"></span>\n<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\">Ви натиснули </span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<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\"></span>\n<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 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 keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> count<span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<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 punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<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>button</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>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>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Зверніть увагу, що <strong>ми продублювали код між цими двома методами життєвого циклу в класі.</strong></p>\n<p>Це все тому, що в багатьох випадках ми хочемо виконати той самий побічний ефект незалжно від того чи компонент тільки змонтувався, або він оновився. Ми б хотіли, щоб ці побічні ефекти викликались після кожного рендеру, але класові React-компоненти не мають методу, який це може зробити. Ми б могли винести окремий метод, але нам все рівно би потрібно було викликати їх у двох місцях.</p>\n<p>Тепер, давайте розглянемо те, як ми можемо реалізувати теж саме, використовуючи хук <code class=\"gatsby-code-text\">useEffect</code>.</p>\n<h3 id=\"example-using-hooks\"><a href=\"#example-using-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<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">import</span> React<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useState<span class=\"token punctuation\">,</span> useEffect <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span></span>\n<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=\"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\">    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></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 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\"></span>\n<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\">Ви натиснули </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\"></span>\n<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 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\"></span>\n<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>button</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>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><strong>Що ж робить <code class=\"gatsby-code-text\">useEffect</code>?</strong> Використовуючи цей хук, ви говорите React зробить щось після рендера компонента. React запам’ятає функцію (тобто “ефект”), яку ви передали та викличе її після того, як внесе зміни в DOM. У цьому ефекті, ми встановлюємо заголовок документа, але ми також можемо виконати або викликати який-небудь імперативний API.</p>\n<p><strong>Чому ж ми викликаємо <code class=\"gatsby-code-text\">useEffect</code> всередині компонента?</strong> Це дає нам доступ до змінної стану <code class=\"gatsby-code-text\">count</code> (або до будь-яких інших пропсів) прямо з ефекту. Нам не потрібен спеціальний API для доступу до цієї змінної — вона вже знаходиться в області видимості функції. Хуки використовують JavaScript-замикання, і таким чином, їм не потрібен спеціальний для React API, так як JavaScript має готове рішення для цієї задачі.</p>\n<p><strong>Чи виконується <code class=\"gatsby-code-text\">useEffect</code> після кожного рендеру?</strong> Так! За замовчуванням він буде виконуватися після кожного рендеру <em>та</em> кожного оновлення. (Ми пізніше розглянемо, <a href=\"#tip-optimizing-performance-by-skipping-effects\">як це налаштувати</a>.) Замість того, щоб сприймати це з позиції “монтування” та “оновлення”, ми радимо просто мати на увазі, що ефекти виконуються після кожного рендеру. React гарантує, що він запустить ефект тільки після того, як DOM оновився.</p>\n<h3 id=\"detailed-explanation\"><a href=\"#detailed-explanation\" 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 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 punctuation\">}</span></code></pre></div>\n<p>Ми оголошуємо змінну стану <code class=\"gatsby-code-text\">count</code> та говоримо React, що ми хочемо використати ефект. Далі, ми передаємо функцію в хук <code class=\"gatsby-code-text\">useEffect</code>. Саме ця функція і <em>буде</em> нашим ефектом. Усередині цього ефекту ми встановлюємо заголовоку документа, використовуючи API браузера <code class=\"gatsby-code-text\">document.title</code>. Ми можемо отримувати доступ до актуального значення змінної <code class=\"gatsby-code-text\">count</code> зсередини ефекту, так як він знаходиться в області видимості нашої функції. Коли React рендерить наш комопонент, він запам’ятовує ефект, який ми використали, і запускає його після того, як оновить DOM. Це буде відбуватися при кожному рендері в тому числі й при первісному.</p>\n<p>Досвідчені JavaScript-розробники можуть помітити, що функція, яку ми передаємо до <code class=\"gatsby-code-text\">useEffect</code>, буде змінюватися при кожному рендері. Насправді, це було зроблено навмисно. Це якраз те, що дає нам змогу отримувати актуальну версію змінної <code class=\"gatsby-code-text\">count</code> зсередини ефекту, не турбуючись про те, що її значення застаріє. Кожен раз при повторному рендері, ми ставимо в чергу <em>новий</em> ефект, який замінює попередній. В певному сенсі, це включає поведінку ефектів до частини результата рендеру, тобто кожен ефект «належить» до певного рендеру. Ми розповімо про переваги цього підходу <a href=\"#explanation-why-effects-run-on-each-update\">далі на цій сторінці</a>.</p>\n<blockquote>\n<p>Порада</p>\n<p>На відміну від <code class=\"gatsby-code-text\">componentDidMount</code> або <code class=\"gatsby-code-text\">componentDidUpdate</code>, ефекти, запланові за допомогою <code class=\"gatsby-code-text\">useEffect</code>, не блокують браузер за спроби оновити екран. Ваш додаток буде швидше реагувати на дії користувача, навіть коли ефект ще не закінчився. Більшості ефектів не потрібно працювати в синхронному режимі. В окремих випадках, коли їм все ж потрібно це робити (наприклад, вимірювання макета), існує спеціальний хук <a href=\"/docs/hooks-reference.html#uselayouteffect\"><code class=\"gatsby-code-text\">useLayoutEffect</code></a> з API ідентичним до <code class=\"gatsby-code-text\">useEffect</code>.</p>\n</blockquote>\n<h2 id=\"effects-with-cleanup\"><a href=\"#effects-with-cleanup\" 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<p>Раніше ми розглядали побічні ефекти, які не вимагали скидання. Однак, є випадки, коли скидання все ж таки необхідне. Наприклад, <strong>нам може знадобитися встановити підписку</strong> на яке-небудь зовнішнє джерело даних. У цьому випадку дуже важливо виконувати скидання, щоб не сталося витоків пам’яті! Давайте порівняємо, як ми можемо це реалізувати за допомогою класів та хуків.</p>\n<h3 id=\"example-using-classes-1\"><a href=\"#example-using-classes-1\" 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-класі, ви, як правило, налаштували би підписку у <code class=\"gatsby-code-text\">componentDidMount</code> та скинули би її у <code class=\"gatsby-code-text\">componentWillUnmount</code>. Наприклад, скажімо, у нас є модуль <code class=\"gatsby-code-text\">ChatAPI</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\">class</span> <span class=\"token class-name\">FriendStatus</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</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\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> isOnline<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 keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">handleStatusChange</span><span class=\"token punctuation\">.</span><span class=\"token function\">bind</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><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 function\">componentDidMount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange</span><span class=\"gatsby-highlight-code-line\">    <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><span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">componentWillUnmount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange</span><span class=\"gatsby-highlight-code-line\">    <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><span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">handleStatusChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">status</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      isOnline<span class=\"token operator\">:</span> status<span class=\"token punctuation\">.</span>isOnline</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=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span>\n  <span class=\"token function\">render</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><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>isOnline <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 keyword\">return</span> <span class=\"token string\">'Завантаження...'</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>isOnline <span class=\"token operator\">?</span> <span class=\"token string\">'Онлайн'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'Офлайн'</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Зверніть увагу, що <code class=\"gatsby-code-text\">componentDidMount</code> та <code class=\"gatsby-code-text\">componentWillUnmount</code> по суті містять ідентичний код. Методи життєвого циклу змушують нас розділяти цю логіку, хоча й концептуально код обох методів відноситься до одного і того ж ефекту.</p>\n<blockquote>\n<p>Примітка</p>\n<p>Уважний читач міг помітити, що для правильної роботи, нашому компоненту також потрібен <code class=\"gatsby-code-text\">componentDidUpdate</code>. Ми повернемося до цього моменту <a href=\"#explanation-why-effects-run-on-each-update\">нижче</a> на цій сторінці.</p>\n</blockquote>\n<h3 id=\"example-using-hooks-1\"><a href=\"#example-using-hooks-1\" 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\">useEffect</code>. Якщо ваш ефект повертає функцію, React виконає її, коли настане час скинути ефект:</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 punctuation\">,</span> <span class=\"token punctuation\">{</span> useState<span class=\"token punctuation\">,</span> useEffect <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">FriendStatus</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> <span class=\"token punctuation\">[</span>isOnline<span class=\"token punctuation\">,</span> setIsOnline<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=\"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\">    <span class=\"token keyword\">function</span> <span class=\"token function\">handleStatusChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">status</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">setIsOnline</span><span class=\"token punctuation\">(</span>status<span class=\"token punctuation\">.</span>isOnline<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><span class=\"gatsby-highlight-code-line\">    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> handleStatusChange<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token comment\">// Зазначаємо, як скинути цей ефект:</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">return</span> <span class=\"token keyword\">function</span> <span class=\"token function\">cleanup</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> handleStatusChange<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><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 keyword\">if</span> <span class=\"token punctuation\">(</span>isOnline <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 keyword\">return</span> <span class=\"token string\">'Завантаження...'</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">return</span> isOnline <span class=\"token operator\">?</span> <span class=\"token string\">'Онлайн'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'Офлайн'</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><strong>Навіщо ми повернули функцію з нашого ефекту?</strong> Це необов’язковий механізм скидання ефектів. Кожен ефект може повернути функцію, яка скине його. Це дає нам можливість об’єднати разом логіку оформлення та скасування підписки. Вони, все-таки, частина одного й того ж ефекту!</p>\n<p><strong>Коли саме React буде скидати ефект?</strong> React буде скидати ефект перед тим, як компонент розмонтується. . Однак, як ми вже знаємо, ефекти виконуються не один раз, а при кожному рендері. Ось чому React <em>також</em> скидає ефект з попереднього рендеру, перед тим, як запустити наступний. Ми розглянемо <a href=\"#explanation-why-effects-run-on-each-update\">чому це дозволяє уникнути багів</a> і <a href=\"#tip-optimizing-performance-by-skipping-effects\">як відмовитися від цієї логіки, якщо це викликає проблеми з продуктивністю</a> далі.</p>\n<blockquote>\n<p>Примітка</p>\n<p>Нам не потрібно повертати іменовану функцію з ефекту. Ми назвали її <code class=\"gatsby-code-text\">cleanup</code>, щоб пояснити її призначення. Ви можете за бажанням повернути стрілкову функцію або назвати її якось інакше.</p>\n</blockquote>\n<h2 id=\"recap\"><a href=\"#recap\" 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<p>Ми дізналися, що за допомогою <code class=\"gatsby-code-text\">useEffect</code>, ми можемо викликати різні побічні ефекти після того, як компонент відрендериться. Деякі ефекти потребують скидання, тому вони повертають відповідну функцію:</p>\n<div class=\"gatsby-highlight\" 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\">handleStatusChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">status</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">setIsOnline</span><span class=\"token punctuation\">(</span>status<span class=\"token punctuation\">.</span>isOnline<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> handleStatusChange<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 punctuation\">{</span>\n      ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> handleStatusChange<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></code></pre></div>\n<p>У деяких ефектах немає етапу скидання, тому вони не повертають нічого.</p>\n<div class=\"gatsby-highlight\" 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    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></code></pre></div>\n<p>Хук ефекту покриває обидва сценарії єдиним API.</p>\n<hr>\n<p><strong>Якщо ви відчуваєте, що ви достатньо розібралися з тим, як працює хук ефекту, ви можете відправитися на <a href=\"/docs/hooks-rules.html\">сторінку про правила хуків</a> прямо зараз.</strong></p>\n<hr>\n<h2 id=\"tips-for-using-effects\"><a href=\"#tips-for-using-effects\" 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<p>Далі, ми поглибимося у деякі особливості хуку <code class=\"gatsby-code-text\">useEffect</code>, про які досвідчені користувачі React напевно вже задумалися. Будь ласка, не змушуйте себе заглиблюватися в ці особливості прямо зараз. Ви можете спершу закріпити вище пройдений матеріал і повернутися сюди пізніше в будь-який момент.</p>\n<h3 id=\"tip-use-multiple-effects-to-separate-concerns\"><a href=\"#tip-use-multiple-effects-to-separate-concerns\" 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#complex-components-become-hard-to-understand\">мотивації</a>, наводить аргументи про те, що на відміну від хуків, класові методи життєвого циклу часто містять логіку, яка ніяк між собою не пов’язана, в той час як пов’язана логіка, розбивається на декілька методів. Далі ми наведемо приклад компонента, який об’єднує в собі логіку лічильника та індикатора статусу нашого друга з попередніх прикладів:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">FriendStatusWithCounter</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</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\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> count<span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> isOnline<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 keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">handleStatusChange</span><span class=\"token punctuation\">.</span><span class=\"token function\">bind</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">componentDidMount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</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><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token 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    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">componentDidUpdate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</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><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token 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>\n\n  <span class=\"token function\">componentWillUnmount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">handleStatusChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">status</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n      isOnline<span class=\"token operator\">:</span> status<span class=\"token punctuation\">.</span>isOnline\n    <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 comment\">// ...</span></code></pre></div>\n<p>Зверніть увагу, що логіка, яка встановлює <code class=\"gatsby-code-text\">document.title</code> розділена між <code class=\"gatsby-code-text\">componentDidMount</code> та <code class=\"gatsby-code-text\">componentDidUpdate</code>. Логіка підписки також розкидана між <code class=\"gatsby-code-text\">componentDidMount</code> та <code class=\"gatsby-code-text\">componentWillUnmount</code>. А метод <code class=\"gatsby-code-text\">componentDidMount</code> містить в собі логіку для обох задач.</p>\n<p>Отже, як можна вирішити цю проблему за допомогою хуків? Так само як <a href=\"/docs/hooks-state.html#tip-using-multiple-state-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\">FriendStatusWithCounter</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> <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 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>    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\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>isOnline<span class=\"token punctuation\">,</span> setIsOnline<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=\"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=\"token keyword\">function</span> <span class=\"token function\">handleStatusChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">status</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">setIsOnline</span><span class=\"token punctuation\">(</span>status<span class=\"token punctuation\">.</span>isOnline<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> handleStatusChange<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 punctuation\">{</span>\n      ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> handleStatusChange<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  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><strong>За допомогою хуків, ми можемо розділити наш код виходячи з того, що він робить</strong>, а не за принципами методів життєвого циклу. React буде виконувати <em>кожен</em> використаний ефект у компоненті, згідно з порядком їх оголошення.</p>\n<h3 id=\"explanation-why-effects-run-on-each-update\"><a href=\"#explanation-why-effects-run-on-each-update\" 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><a href=\"#example-using-classes-1\">Раніше на цій сторінці</a>, ми розглядали приклад з компонентом <code class=\"gatsby-code-text\">FriendStatus</code>, який відображає в мережі наш друг чи ні. Наш клас бере <code class=\"gatsby-code-text\">friend.id</code> з <code class=\"gatsby-code-text\">this.props</code>, підписується на статус друга після того, як компонент змонтувався, і відписується під час розмонтування:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">  <span class=\"token function\">componentDidMount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">componentWillUnmount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span></code></pre></div>\n<p><strong>Але що ж станеться, якщо проп <code class=\"gatsby-code-text\">friend</code> зміниться</strong>, поки компонент все ще знаходиться на екрані? Наш компонент буде відображати статус в мережі вже якогось іншого друга. Це якраз і є баг. Це також може привести до витоку пам’яті або взагалі до вильоту нашого додатку при розмонтуванні, так як метод відписки буде використовувати неправильний ID друга, від якого ми хочемо відписатися.</p>\n<p>У класовому компоненті нам би довелося додати <code class=\"gatsby-code-text\">componentDidUpdate</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\">componentDidMount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange\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 function\">componentDidUpdate</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">prevProps</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token comment\">// Відписка від попереднього friend.id</span></span><span class=\"gatsby-highlight-code-line\">    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span></span><span class=\"gatsby-highlight-code-line\">      prevProps<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange</span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token comment\">// Підписка на наступний friend.id</span></span><span class=\"gatsby-highlight-code-line\">    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange</span><span class=\"gatsby-highlight-code-line\">    <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\">componentWillUnmount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleStatusChange\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\">componentDidUpdate</code> належним чином — це один з найпоширеніших джерел багів в React-додатках.</p>\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\">FriendStatus</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\">// ...</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    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> handleStatusChange<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 punctuation\">{</span>\n      ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> handleStatusChange<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></code></pre></div>\n<p>Цього бага в даному компоненті немає. (Але ми і не змінили там нічого)</p>\n<p>Тут немає ніякого особливого коду для вирішення проблем з оновленнями, так як <code class=\"gatsby-code-text\">useEffect</code> вирішує їх <em>за замовчуванням</em>. Він скидає попередні ефекти перш ніж виконати нові. Щоб показати це на практиці, давайте розглянемо послідовність підписок і відписок, які цей компонент може виконати протягом деякого часу.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token comment\">// Монтуємо з пропсами { friend: { id: 100 } }</span>\nChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span><span class=\"token number\">100</span><span class=\"token punctuation\">,</span> handleStatusChange<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>     <span class=\"token comment\">// Виконуємо перший ефект</span>\n\n<span class=\"token comment\">// Оновлюємо з пропсами { friend: { id: 200 } }</span>\nChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span><span class=\"token number\">100</span><span class=\"token punctuation\">,</span> handleStatusChange<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Скидаємо попередній ефект</span>\nChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span><span class=\"token number\">200</span><span class=\"token punctuation\">,</span> handleStatusChange<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>     <span class=\"token comment\">// Виконуємо наступний ефект</span>\n\n<span class=\"token comment\">// Оновлюємо з пропсами { friend: { id: 300 } }</span>\nChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span><span class=\"token number\">200</span><span class=\"token punctuation\">,</span> handleStatusChange<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Скидаємо попередній ефект</span>\nChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span><span class=\"token number\">300</span><span class=\"token punctuation\">,</span> handleStatusChange<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>     <span class=\"token comment\">// Виконуємо наступний ефект</span>\n\n<span class=\"token comment\">// Розмонтуємо</span>\nChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span><span class=\"token number\">300</span><span class=\"token punctuation\">,</span> handleStatusChange<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Скидаємо останній ефект</span></code></pre></div>\n<p>Ця логіка за замовчуванням гарантує узгодженість виконуваних нами дій і запобігає багам, поширених в класових компонентах через упущену логіку оновлення.</p>\n<h3 id=\"tip-optimizing-performance-by-skipping-effects\"><a href=\"#tip-optimizing-performance-by-skipping-effects\" 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\">prevProps</code> або <code class=\"gatsby-code-text\">prevState</code> всередині <code class=\"gatsby-code-text\">componentDidUpdate</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">componentDidUpdate</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">prevProps<span class=\"token punctuation\">,</span> prevState</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>prevState<span class=\"token punctuation\">.</span>count <span class=\"token operator\">!==</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>count<span class=\"token punctuation\">)</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><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token 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>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Цю логіку доводиться використовувати досить часто, тому ми вирішили вбудувати її в API хука <code class=\"gatsby-code-text\">useEffect</code>. Ви можете зробити так, щоб React <em>пропускав</em> виклик ефекту, якщо певні значення залишилися без змін між наступними рендерами. Щоб зробити це, передайте масив в <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 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=\"gatsby-highlight-code-line\"><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Ефект перезапускається тільки якщо count змінився</span></span></code></pre></div>\n<p>У цьому прикладі, ми передаємо <code class=\"gatsby-code-text\">[count]</code> другим аргументом. Але що це взагалі означає? Це означає, що якщо <code class=\"gatsby-code-text\">count</code> дорівнюватиме <code class=\"gatsby-code-text\">5</code> і наш компонент повторно відрендериться з тим самим значенням <code class=\"gatsby-code-text\">count = 5</code>, React порівняє <code class=\"gatsby-code-text\">[5]</code> з попереднього рендеру і <code class=\"gatsby-code-text\">[5]</code> з наступного рендеру. Так як, все елементи масиву залишилися без змін (<code class=\"gatsby-code-text\">5 === 5</code>), React пропустить цей ефект. Це і є оптимізація даного процесу.</p>\n<p>Коли при наступному рендері наша змінна <code class=\"gatsby-code-text\">count</code> оновиться до <code class=\"gatsby-code-text\">6</code>, React порівняє елементи в масиві <code class=\"gatsby-code-text\">[5]</code> з попереднього рендеру і елементи масиву<code class=\"gatsby-code-text\">[6]</code> з наступного рендеру. Цього разу, React виконає наш ефект, так як <code class=\"gatsby-code-text\">5 !== 6</code>. Якщо у вас буде кілька елементів в масиві, React виконуватиме наш ефект, в тому випадку, коли хоча б один з них буде відрізнятися.</p>\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=\"token keyword\">function</span> <span class=\"token function\">handleStatusChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">status</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setIsOnline</span><span class=\"token punctuation\">(</span>status<span class=\"token punctuation\">.</span>isOnline<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">subscribeToFriendStatus</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> handleStatusChange<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 punctuation\">{</span>\n    ChatAPI<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribeFromFriendStatus</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> handleStatusChange<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <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>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Повторно підписатися, тільки якщо props.friend.id змінився</span></span></code></pre></div>\n<p>У майбутньому, другий аргумент можливо буде додаватися автоматично за допомогою трансформації під час виконання.</p>\n<blockquote>\n<p>Примітка</p>\n<p>Якщо ви хочете використати цю оптимізацію, зверніть увагу на те, щоб масив включав в себе <strong>усі значення з області видимості компонента (такі як пропси і стан), які можуть змінюватися з плином часу, і які будуть використовуватися ефектом</strong>. В іншому випадку, ваш код буде посилатися на застаріле значення з попередніх рендерів. Дізнайтеся більше про те, <a href=\"/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies\">як діяти з функціями</a> і <a href=\"/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often\">що робити з часто змінюваними масивами</a>.</p>\n<p>Якщо ви хочете запустити ефект і скинути його тільки один раз (при монтуванні і розмонтуванні), ви можете передати порожній масив (<code class=\"gatsby-code-text\">[]</code>) другим аргументом. React вважатиме, що ваш ефект не залежить від <em>будь-яких</em> значень з пропсов або стану і тому не буде виконувати повторних рендерів. Це не обробляється як особливий випадок — він безпосередньо випливає з логіки роботи масивів залежностей.</p>\n<p>Якщо ви передасте порожній масив (<code class=\"gatsby-code-text\">[]</code>), пропси і стан всередині ефекту завжди матимуть значення, присвоєні їм спочатку. Хоча передача <code class=\"gatsby-code-text\">[]</code> другим аргументом ближче за моделлю мислення  до знайомих <code class=\"gatsby-code-text\">componentDidMount</code> та <code class=\"gatsby-code-text\">componentWillUnmount</code>, зазвичай є <a href=\"/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies\">кращі</a> <a href=\"/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often\">способи</a> уникнути частих повторних рендерів. Не забувайте, що React відкладає виконання <code class=\"gatsby-code-text\">useEffect</code>, поки браузер не відмалює усі зміни, тому виконання додаткової роботи не є суттєвою проблемою.</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<h2 id=\"next-steps\"><a href=\"#next-steps\" 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<p>Вітаємо! Це була довга сторінка, але ми сподіваємося, що під кінець, у нас вийшло відповісти на всі ваші запитання з приводу роботи ефектів. Ви вже дізналися про хук стану і про хук ефекту, і тепер є <em>дуже багато</em> речей, які ви можете робити, об’єднавши їх разом. Вони охоплюють більшість випадків для використання класів. В інших випадках, вам можуть стати в нагоді <a href=\"/docs/hooks-reference.html\">додаткові хукі</a>.</p>\n<p>Ми також дізналися, як хукі позбавляють від проблем описаних у <a href=\"/docs/hooks-intro.html#motivation\">мотивації</a>. Ми побачили, як за допомогою скидання ефектів нам вдається уникнути повторення коду в <code class=\"gatsby-code-text\">componentDidUpdate</code> і <code class=\"gatsby-code-text\">componentWillUnmount</code>, об’єднати пов’язаний код разом і захистити наш код від багів. Ми також розглянули, як можна розділяти наші ефекти за змістом і призначенням, що раніше було неможливо в класах.</p>\n<p>На цьому етапі, ви, можливо, ставите питанням, як хукі працюють в цілому. Як React розуміє, яка змінна стану відповідає якому виклику <code class=\"gatsby-code-text\">useState</code> між повторними рендерами? Як React «зіставляє» попередні і наступні ефекти при кожному оновленні?  <strong>На наступній сторінці, ми дізнаємося про <a href=\"/docs/hooks-rules.html\">правила хуків</a>, так як вони є запорукою належного функціонування хуків.</strong></p>","frontmatter":{"title":"Використовуємо хук ефекту","next":"hooks-rules.html","prev":"hooks-state.html"},"fields":{"path":"content/docs/hooks-effect.md","slug":"docs/hooks-effect.html"}}},"pageContext":{"slug":"docs/hooks-effect.html"}},"staticQueryHashes":[]}