{"componentChunkName":"component---src-templates-docs-js","path":"/docs/hooks-rules.html","result":{"data":{"markdownRemark":{"html":"<p><em>Hooks</em> são uma nova adição ao React 16.8. Eles permitem que você use o state e outros recursos do React sem escrever uma classe.</p>\n<p>Hooks são funções JavaScript, mas você precisa seguir duas regras ao utilizá-los. Nós providenciamos um <a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">plugin ESLint</a> para aplicar essas regras automaticamente:</p>\n<h3 id=\"only-call-hooks-at-the-top-level\"><a href=\"#only-call-hooks-at-the-top-level\" 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>Use Hooks Apenas no Nível Superior </h3>\n<p><strong>Não use Hooks dentro de loops, regras condicionais ou funções aninhadas (funções dentro de funções).</strong> Em vez disso, sempre use Hooks no nível superior de sua função React. Seguindo essas regras, você garante que os Hooks serão chamados na mesma ordem a cada vez que o componente renderizar. É isso que permite que o React preserve corretamente o estado dos Hooks quando são usados várias chamadas a <code class=\"gatsby-code-text\">useState</code> e <code class=\"gatsby-code-text\">useEffect</code> na mesma função. (Se você ficou curioso, iremos explicar isso melhor <a href=\"#explanation\">abaixo</a>.)</p>\n<h3 id=\"only-call-hooks-from-react-functions\"><a href=\"#only-call-hooks-from-react-functions\" 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>Use Hooks Apenas Dentro de Funções do React </h3>\n<p><strong>Não use Hooks dentro de funções JavaScript comuns.</strong> Em vez disso, você pode:</p>\n<ul>\n<li>✅  Chamar Hooks em componentes React.</li>\n<li>✅  Chamar Hooks dentro de Hooks Customizados (Nós iremos aprender sobre eles <a href=\"/docs/hooks-custom.html\">na próxima página.</a>).</li>\n</ul>\n<p>Seguindo essas regras, você garante que toda lógica de estado (<code class=\"gatsby-code-text\">state</code>) no componente seja claramente visível no código fonte.</p>\n<h2 id=\"eslint-plugin\"><a href=\"#eslint-plugin\" 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>ESLint Plugin </h2>\n<p>Nós liberamos um plugin ESLint chamado <a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">eslint-plugin-react-hooks</code></a> que aplica essas duas regras. Se você desejar pode adicionar este plugin ao seu projeto, dessa forma:</p>\n<p>Esse plugin está incluindo por padrão no <a href=\"/docs/create-a-new-react-app.html#create-react-app\">Create React App</a>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"gatsby-code-bash\"><code class=\"gatsby-code-bash\"><span class=\"token function\">npm</span> <span class=\"token function\">install</span> eslint-plugin-react-hooks --save-dev</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token comment\">// Sua Configuração ESLint</span>\n\n<span class=\"token punctuation\">{</span>\n  <span class=\"token string\">\"plugins\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token comment\">// ...</span>\n    <span class=\"token string\">\"react-hooks\"</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token string\">\"rules\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// ...</span>\n    <span class=\"token string\">\"react-hooks/rules-of-hooks\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"error\"</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// Checks rules of Hooks</span>\n    <span class=\"token string\">\"react-hooks/exhaustive-deps\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"warn\"</span> <span class=\"token comment\">// Checks effect dependencies</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><strong>Você pode pular para próxima página agora, onde explica melhor como escrever <a href=\"/docs/hooks-custom.html\">seus próprios Hooks</a>.</strong> Nessa página continuaremos explicando o motivo por trás dessas regras.</p>\n<h2 id=\"explanation\"><a href=\"#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>Explicação </h2>\n<p>Assim como <a href=\"/docs/hooks-state.html#tip-using-multiple-state-variables\">aprendemos anteriormente</a>, nós podemos usar diversos Hooks (States ou Effects) em um único componente:</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\">Form</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// 1. Use a variável de estado (state) name</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>name<span class=\"token punctuation\">,</span> setName<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Mary'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// 2. Use um efeito para persistir o formulário</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span> <span class=\"token function\">persistForm</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">setItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">'formData'</span><span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// 3. Use a variável de estado (state) surname</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>surname<span class=\"token punctuation\">,</span> setSurname<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Poppins'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// 4. Use um efeito para atualizar o título</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span> <span class=\"token function\">updateTitle</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> name <span class=\"token operator\">+</span> <span class=\"token string\">' '</span> <span class=\"token operator\">+</span> surname<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// ....</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Agora, como o React sabe qual o estado (<code class=\"gatsby-code-text\">state</code>) correspondente ao <code class=\"gatsby-code-text\">useState</code> chamado? A resposta é que o <strong>React depende da ordem em que os Hooks são chamados.</strong> Nosso exemplo funciona porque a ordem de chamada dos Hooks é a mesma sempre que o componente é renderizado:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token comment\">// ------------</span>\n<span class=\"token comment\">// Primeira renderização</span>\n<span class=\"token comment\">// ------------</span>\n<span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Mary'</span><span class=\"token punctuation\">)</span>           <span class=\"token comment\">// 1. Inicializa a variável de estado (state) name com 'Mary'</span>\n<span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span>persistForm<span class=\"token punctuation\">)</span>     <span class=\"token comment\">// 2. Adiciona um efeito para persistir o formulário</span>\n<span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Poppins'</span><span class=\"token punctuation\">)</span>        <span class=\"token comment\">// 3. Inicializa a variável de estado (state) surname com 'Poppins'</span>\n<span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span>updateTitle<span class=\"token punctuation\">)</span>     <span class=\"token comment\">// 4. Adiciona um efeito para atualizar o título</span>\n\n<span class=\"token comment\">// -------------</span>\n<span class=\"token comment\">// Segunda renderização</span>\n<span class=\"token comment\">// -------------</span>\n<span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Mary'</span><span class=\"token punctuation\">)</span>           <span class=\"token comment\">// 1. Lê a variável de estado (state) name (argumento ignorado)</span>\n<span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span>persistForm<span class=\"token punctuation\">)</span>     <span class=\"token comment\">// 2. Substitui o efeito para persistir no formulário</span>\n<span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Poppins'</span><span class=\"token punctuation\">)</span>        <span class=\"token comment\">// 3. Lê a variável de estado (state) surname (argumento ignorado)</span>\n<span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span>updateTitle<span class=\"token punctuation\">)</span>     <span class=\"token comment\">// 4. Substitui o efeito que atualiza o título</span>\n\n<span class=\"token comment\">// ...</span></code></pre></div>\n<p>Enquanto a ordem dos Hooks chamados for a mesma entre as renderizações, o React pode associar um estado (<code class=\"gatsby-code-text\">state</code>) local a cada um deles. Mas o que acontece se colocarmos uma chamada de Hook (por exemplo, o efeito <code class=\"gatsby-code-text\">persistForm</code>) dentro de uma condição?</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token comment\">// 🔴 Nós estaremos quebrando a primeira regra por usar um Hook dentro de uma condição</span>\n<span class=\"token keyword\">if</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 function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span> <span class=\"token function\">persistForm</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">setItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">'formData'</span><span class=\"token punctuation\">,</span> name<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 punctuation\">}</span></code></pre></div>\n<p>A condição <code class=\"gatsby-code-text\">name !== &#39;&#39;</code> é <code class=\"gatsby-code-text\">true</code> na primeira renderização, então chamamos o Hook dentro da condição. Entretanto, na próxima renderização o usuário pode limpar o formulário, fazendo com que a condição seja <code class=\"gatsby-code-text\">false</code>. Agora que pulamos este Hook durante a renderização, a ordem das chamadas dos Hooks foi alterada:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Mary'</span><span class=\"token punctuation\">)</span>           <span class=\"token comment\">// ✅  1. Lê a variável de estado (state) name (argumento é ignorado)</span>\n<span class=\"token comment\">// useEffect(persistForm)  // 🔴  Agora, este Hook foi ignorado!</span>\n<span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Poppins'</span><span class=\"token punctuation\">)</span>        <span class=\"token comment\">// 🔴  Na ordem era pra ser 2 (mas foi 3). Falha ao ler a variável de estado (state) surname</span>\n<span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span>updateTitle<span class=\"token punctuation\">)</span>     <span class=\"token comment\">// 🔴  Na ordem era pra ser 3 (mas foi 4). Falha ao substituir o efeito</span></code></pre></div>\n<p>O React não saberia o que retornar na segunda chamada do Hook <code class=\"gatsby-code-text\">useState</code>. O React esperava que a segunda chamada de Hook nesse componente fosse ao efeito <code class=\"gatsby-code-text\">persistForm</code>, assim como aconteceu na renderização anterior, mas a ordem foi alterada. A partir daí, toda vez que um Hook for chamado depois daquele que nós pulamos, o próximo também se deslocaria, levando a erros.</p>\n<p><strong>É por isso que os Hooks devem ser chamados no nível superior de nosso componente.</strong> Se nós queremos executar um efeito condicional, nós podemos colocar a condição <em><strong>dentro</strong></em> de nosso Hook:</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 keyword\">function</span> <span class=\"token function\">persistForm</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// 👍  Legal! Agora não quebramos mais a primeira regra.</span>\n  <span class=\"token keyword\">if</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    localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">setItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">'formData'</span><span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><strong>Note que você não precisa se preocupar com esse problema, se você usar a <a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">regra fornecida no plugin do ESLint</a></strong>. Mas agora você também sabe o <em>porquê</em> dos Hooks funcionarem dessa maneira, e quais os problemas que essas regras previnem.</p>\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>Próximos Passos </h2>\n<p>Finalmente, estamos prontos para aprender sobre como <a href=\"/docs/hooks-custom.html\">escrever nossos próprios Hooks</a>! Hooks Customizados permitem você combinar Hooks fornecidos pelo React em suas próprias abstrações, e reusar a lógica do <code class=\"gatsby-code-text\">state</code> entre diferentes componentes.</p>","frontmatter":{"title":"Regras dos Hooks","next":"hooks-custom.html","prev":"hooks-effect.html"},"fields":{"path":"content/docs/hooks-rules.md","slug":"docs/hooks-rules.html"}}},"pageContext":{"slug":"docs/hooks-rules.html"}},"staticQueryHashes":[]}