{"componentChunkName":"component---src-templates-docs-js","path":"/docs/hooks-custom.html","result":{"data":{"markdownRemark":{"html":"<p><em>Хуки</em> — це новинка в React 16.8. Вони дозволяють вам використовувати стан та інші можливості React без написання класу.</p>\n<p>Створення власних хуків дозволить вам винести логіку компонента у функції, придатні для повторного використання.</p>\n<p>Коли ми розглядали <a href=\"/docs/hooks-effect.html#example-using-hooks-1\">використання хука ефекту</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 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=\"gatsby-highlight-code-line\">  <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></span><span class=\"gatsby-highlight-code-line\"></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 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 keyword\">return</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\">      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>Скажімо, що в нашому додатку чату також є список контактів і ми хочемо відобразити зеленим кольором імена користувачів, які знаходяться в мережі. Ми б могли скопіювати і вставити наведену вище логіку в наш компонент <code class=\"gatsby-code-text\">FriendListItem</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\">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\">FriendListItem</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 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></span><span class=\"gatsby-highlight-code-line\"></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 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 keyword\">return</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\">      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\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>li</span> <span class=\"token attr-name\">style</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span> color<span class=\"token operator\">:</span> isOnline <span class=\"token operator\">?</span> <span class=\"token string\">'green'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'black'</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><span class=\"token punctuation\">{</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>name<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>li</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\">FriendStatus</code> і <code class=\"gatsby-code-text\">FriendListItem</code> розділяли цю логіку.</p>\n<p>Інколи треба повторно використовувати однакову логіку стану в декількох компонентах. Традиційно використовувалися два підходи: <a href=\"/docs/higher-order-components.html\">компоненти вищого порядку</a> та <a href=\"/docs/render-props.html\">рендер-пропси</a>. Зараз ми побачимо, як за допомогою хуків вирішити багато схожих проблем без додавання непотрібних компонентів у дерево.</p>\n<h2 id=\"extracting-a-custom-hook\"><a href=\"#extracting-a-custom-hook\" 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>Коли ми хочемо, щоб дві функції JavaScript розділяли спільну логіку, ми виокремлюємо її в третю функцію. Компоненти та хуки є функціями, а тому це правило працює і для них!</p>\n<p><strong>Користувацький хук — це JavaScript-функція, ім’я якої починається з ”<code class=\"gatsby-code-text\">use</code>”, і яка може викликати інші хуки.</strong> Наприклад, <code class=\"gatsby-code-text\">useFriendStatus</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\">import</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=\"gatsby-highlight-code-line\"><span class=\"token keyword\">function</span> <span class=\"token function\">useFriendStatus</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">friendID</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span>  <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=\"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>friendID<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>friendID<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\n  <span class=\"token keyword\">return</span> isOnline<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Тут немає нічого нового — логіка повністю скопійована з компонентів вище. Так само як і в компонентах, ви маєте впевнитись, що не використовуєте хуки в межах умовних операторів і викликаєте їх на верхньому рівні вашого власного хука.</p>\n<p>На відміну від React-компонента, користувацький хук не повинен мати особливої сигнатури. Ми можемо вирішувати, що він прийматиме як аргументи, яке значення він буде повертати і чи буде повертати його взагалі. Іншими словами, все як для звичайної функції. Ім’я функції-хука варто завжди починати з <code class=\"gatsby-code-text\">use</code>, щоб ви могли відразу розпізнати, що для неї виконуються <a href=\"/docs/hooks-rules.html\">правила хуків</a>.</p>\n<p>Метою нашого <code class=\"gatsby-code-text\">useFriendStatus</code> хука є підписка на статус друга. Саме тому він приймає <code class=\"gatsby-code-text\">friendID</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\">useFriendStatus</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">friendID</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=\"token comment\">// ...</span>\n\n  <span class=\"token keyword\">return</span> isOnline<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Тепер давайте поглянемо, як ми можемо використовувати наш користувацький хук.</p>\n<h2 id=\"using-a-custom-hook\"><a href=\"#using-a-custom-hook\" 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\">FriendStatus</code> і <code class=\"gatsby-code-text\">FriendListItem</code>. Кожен з них хоче знати, чи знаходиться друг у мережі.</p>\n<p>Тепер, коли ми виокремили цю логіку в хук <code class=\"gatsby-code-text\">useFriendStatus</code>, ми можемо <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\">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=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> isOnline <span class=\"token operator\">=</span> <span class=\"token function\">useFriendStatus</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>\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<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\">FriendListItem</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 keyword\">const</span> isOnline <span class=\"token operator\">=</span> <span class=\"token function\">useFriendStatus</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>\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>li</span> <span class=\"token attr-name\">style</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span> color<span class=\"token operator\">:</span> isOnline <span class=\"token operator\">?</span> <span class=\"token string\">'green'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'black'</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><span class=\"token punctuation\">{</span>props<span class=\"token punctuation\">.</span>friend<span class=\"token punctuation\">.</span>name<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>li</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>Чи є цей код еквівалентним початковим прикладам?</strong> Так, він працює абсолютно таким самим чином. Придивіться ближче і ви побачите, що ми не внесли ніяких змін у логіку. Все, що ми зробили, це виокремили спільних для обох функцій код в окрему функцію. <strong>Користувацькі хуки — це більше домовленість, яка природньо випливає з дизайну хуків, а не особливість функціоналу React.</strong></p>\n<p><strong>Чи повинен я починати імена моїх хуків з “<code class=\"gatsby-code-text\">use</code>”?</strong> Так, будь ласка. Ця домовленість є дуже важливою. Без неї ми не зможемо автоматично перевіряти порушення <a href=\"/docs/hooks-rules.html\">правил хуків</a>, тому що ми не зможемо визначити, чи містить певна функція виклики хуків.</p>\n<p><strong>Чи є однаковим стан двох компонентів, які використовують той самий хук?</strong> Ні. Користувацькі хуки — це механізм повторного використання <em>логіки зі станом</em> (наприклад, налаштування підписки і збереження поточного значення), але кожного разу, коли ви використовуєте користувацький хук, увесь стан та ефекти всередині нього є повністю незалежними.</p>\n<p><strong>Як користувацький хук отримує власний ізольований стан?</strong> Кожен <em>виклик</em> хука отримує ізольований стан. Незважаючи на те, що ми напряму викликаємо <code class=\"gatsby-code-text\">useFriendStatus</code>, з точки зору React наш компонент просто викликає <code class=\"gatsby-code-text\">useState</code> і <code class=\"gatsby-code-text\">useEffect</code>. І як ми <a href=\"/docs/hooks-state.html#tip-using-multiple-state-variables\">дізналися</a> <a href=\"/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns\">раніше</a>, ми можемо викликати <code class=\"gatsby-code-text\">useState</code> та <code class=\"gatsby-code-text\">useEffect</code> багато разів в одному компоненті і при цьому вони будуть повністю незалежними.</p>\n<h3 id=\"tip-pass-information-between-hooks\"><a href=\"#tip-pass-information-between-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<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\">const</span> friendList <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n  <span class=\"token punctuation\">{</span> id<span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> name<span class=\"token operator\">:</span> <span class=\"token string\">'Маруся'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">{</span> id<span class=\"token operator\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> name<span class=\"token operator\">:</span> <span class=\"token string\">'Гриць'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">{</span> id<span class=\"token operator\">:</span> <span class=\"token number\">3</span><span class=\"token punctuation\">,</span> name<span class=\"token operator\">:</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>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">ChatRecipientPicker</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>recipientID<span class=\"token punctuation\">,</span> setRecipientID<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\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> isRecipientOnline <span class=\"token operator\">=</span> <span class=\"token function\">useFriendStatus</span><span class=\"token punctuation\">(</span>recipientID<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><span class=\"token class-name\">Circle</span></span> <span class=\"token attr-name\">color</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>isRecipientOnline <span class=\"token operator\">?</span> <span class=\"token string\">'green'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'red'</span><span class=\"token punctuation\">}</span></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>select</span>\n        <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>recipientID<span class=\"token punctuation\">}</span></span>\n        <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\">setRecipientID</span><span class=\"token punctuation\">(</span><span class=\"token function\">Number</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 class=\"token punctuation\">}</span></span>\n      <span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">        </span><span class=\"token punctuation\">{</span>friendList<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">friend</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>option</span> <span class=\"token attr-name\">key</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>friend<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">}</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>friend<span class=\"token punctuation\">.</span>id<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 punctuation\">{</span>friend<span class=\"token punctuation\">.</span>name<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>option</span><span class=\"token punctuation\">></span></span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><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>select</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>Ми зберігаємо поточний ID друга у змінній стану <code class=\"gatsby-code-text\">recipientID</code> і оновлюємо її, якщо користувач обирає іншого друга в <code class=\"gatsby-code-text\">&lt;select&gt;</code>.</p>\n<p>Оскільки виклик хука <code class=\"gatsby-code-text\">useState</code> надає нам останнє значення змінної стану <code class=\"gatsby-code-text\">recipientID</code>, ми можемо передати його у наш користувацький хук <code class=\"gatsby-code-text\">useFriendStatus</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> <span class=\"token punctuation\">[</span>recipientID<span class=\"token punctuation\">,</span> setRecipientID<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\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> isRecipientOnline <span class=\"token operator\">=</span> <span class=\"token function\">useFriendStatus</span><span class=\"token punctuation\">(</span>recipientID<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Це дозволяє нам дізнатись, чи є <em>наразі обраний</em> друг у мережі. Якщо ми оберемо іншого друга і оновимо змінну стану <code class=\"gatsby-code-text\">recipientID</code>, наш хук <code class=\"gatsby-code-text\">useFriendStatus</code> відпишеться від попередньо обраного друга і підпишеться на статус щойно обраного.</p>\n<h2 id=\"useyourimagination\"><a href=\"#useyourimagination\" 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\">useYourImagination()</code> </h2>\n<p>Користувацькі хуки пропонують раніше неможливу у React-компонентах гнучкість використання спільної логіки. Ви можете писати користувацькі хуки, що охоплюють широкий спектр випадків, таких як: обробка форм, анімація, декларативні підписки, таймери і, певно, багато інших про які ми навіть не розглянули. Навіть більше, ви можете створювати хуки настільки ж прості у використанні, як і звичайні функції, які підтримує React.</p>\n<p>Спробуйте уникнути додавання абстракції на ранніх етапах. Зараз, коли функціональні компоненти можуть робити більше, цілком можливо, що середній функціональний компонент у вашій кодовій базі стане довшим. Це цілком нормально і не думайте, що ви <em>повинні</em> негайно розділити його на хуки. Але ми також рекомендуємо вам помічати випадки, в яких користувацький хук може приховати складну логіку за простим інтерфейсом чи допоможе розплутати заплутаний компонент.</p>\n<p>Наприклад, ви хочете мати складний компонент, що містить багато локальних змінних стану і керується особливим чином. <code class=\"gatsby-code-text\">useState</code> не спрощує централізацію логіки оновлення, а тому ви можете захотіти переписати його у вигляді редюсера <a href=\"https://redux.js.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Redux</a>:</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\">todosReducer</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state<span class=\"token punctuation\">,</span> action</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>action<span class=\"token punctuation\">.</span>type<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">case</span> <span class=\"token string\">'add'</span><span class=\"token operator\">:</span>\n      <span class=\"token keyword\">return</span> <span class=\"token punctuation\">[</span><span class=\"token operator\">...</span>state<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n        text<span class=\"token operator\">:</span> action<span class=\"token punctuation\">.</span>text<span class=\"token punctuation\">,</span>\n        completed<span class=\"token operator\">:</span> <span class=\"token boolean\">false</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 keyword\">default</span><span class=\"token operator\">:</span>\n      <span class=\"token keyword\">return</span> state<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Редюсери дуже зручні для тестування в ізоляції і масштабування для вираження більш складної логіки оновлення. За необхідності ви можете розбити їх на менші за об’ємом редюсери. Однак вам можуть подобатися переваги використання локального стану React або ж ви не хочете встановлювати додаткову бібліотеку.</p>\n<p>А що, якби ми могли написати хук <code class=\"gatsby-code-text\">useReducer</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 keyword\">function</span> <span class=\"token function\">useReducer</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">reducer<span class=\"token punctuation\">,</span> initialState</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>initialState<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">dispatch</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">action</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> nextState <span class=\"token operator\">=</span> <span class=\"token function\">reducer</span><span class=\"token punctuation\">(</span>state<span class=\"token punctuation\">,</span> action<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">setState</span><span class=\"token punctuation\">(</span>nextState<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>state<span class=\"token punctuation\">,</span> dispatch<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\">Todos</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>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 class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">function</span> <span class=\"token function\">handleAddClick</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">text</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 punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <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\">useReducer</code> до React. Ви знайдете його разом з іншими вбудованими хуками у <a href=\"/docs/hooks-reference.html\">API-довіднику хуків</a>.</p>","frontmatter":{"title":"Створення користувацьких хуків","next":"hooks-reference.html","prev":"hooks-rules.html"},"fields":{"path":"content/docs/hooks-custom.md","slug":"docs/hooks-custom.html"}}},"pageContext":{"slug":"docs/hooks-custom.html"}},"staticQueryHashes":[]}