{"componentChunkName":"component---src-templates-blog-js","path":"/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html","result":{"data":{"markdownRemark":{"html":"<p>A documentação para <code class=\"gatsby-code-text\">componentWillReceiveProps</code> diz que <code class=\"gatsby-code-text\">componentWillReceiveProps</code> será invocado quando as props mudam como resultado de uma re-renderização. Algumas pessoas assumem que isso significa “se <code class=\"gatsby-code-text\">componentWillReceiveProps</code> é chamado, então as props devem ter mudado”, mas essa conclusão é logicamente incorreta.</p>\n<p>O princípio orientador é um dos meus favoritos da lógica/matemática formal:</p>\n<blockquote>\n<p>A implica B não implica B implica A</p>\n</blockquote>\n<p>Exemplo: “Se eu comer comida mofada, eu ficarei doente” não implica “se estou doente, então eu devo ter comido comida mofada”. Existem muitas outras razões pelas quais eu poderia estar me sentindo doente. Por exemplo, a gripe tem circulado no escritório. Da mesma forma, existem várias razões para que <code class=\"gatsby-code-text\">componentWillReceiveProps</code> seja chamado, mesmo que as props não tenham mudado.</p>\n<p>Se você não acredita em mim, chame <code class=\"gatsby-code-text\">ReactDOM.render()</code> três vezes com exatamente as mesmas props, e tente prever o número de vezes que <code class=\"gatsby-code-text\">componentWillReceiveProps</code> será chamado:</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\">Component</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\">componentWillReceiveProps</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">nextProps</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'componentWillReceiveProps'</span><span class=\"token punctuation\">,</span> nextProps<span class=\"token punctuation\">.</span>data<span class=\"token punctuation\">.</span>bar<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</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 tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Bar </span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>data<span class=\"token punctuation\">.</span>bar<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>div</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">var</span> container <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'container'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">var</span> mydata <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>bar<span class=\"token operator\">:</span> <span class=\"token string\">'drinks'</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\nReactDOM<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Component</span></span> <span class=\"token attr-name\">data</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>mydata<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> container<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nReactDOM<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Component</span></span> <span class=\"token attr-name\">data</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>mydata<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> container<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nReactDOM<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Component</span></span> <span class=\"token attr-name\">data</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>mydata<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> container<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Neste caso, a resposta é “2”. React chama <code class=\"gatsby-code-text\">componentWillReceiveProps</code> duas vezes (uma vez para cada um dos dois updates). Nas duas vezes, o valor “drinks” é impresso (isto é, as props não mudaram).</p>\n<p>Para entender o porquê, precisamos pensar no que <em>poderia</em> ter acontecido. Os dados <em>poderiam</em> ter mudado entre a renderização inicial e as duas atualizações subsequentes, se o código tivesse realizado uma mutação como essa:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">var</span> mydata <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>bar<span class=\"token operator\">:</span> <span class=\"token string\">'drinks'</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\nReactDOM<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Component</span></span> <span class=\"token attr-name\">data</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>mydata<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> container<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nmydata<span class=\"token punctuation\">.</span>bar <span class=\"token operator\">=</span> <span class=\"token string\">'food'</span>\nReactDOM<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Component</span></span> <span class=\"token attr-name\">data</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>mydata<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> container<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nmydata<span class=\"token punctuation\">.</span>bar <span class=\"token operator\">=</span> <span class=\"token string\">'noise'</span>\nReactDOM<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Component</span></span> <span class=\"token attr-name\">data</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>mydata<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> container<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>React não tem como saber que os dados não foram alterados. Portanto, React precisa chamar <code class=\"gatsby-code-text\">componentWillReceiveProps</code>, porque o componente precisa ser notificado sobre as novas props (mesmo se as novas props forem iguais as props antigas).</p>\n<p>Você pode pensar que o React poderia apenas usar verificações mais inteligentes para igualidade, mas há alguns problemas com essa ideia:</p>\n<ul>\n<li>O antigo <code class=\"gatsby-code-text\">mydata</code> e o novo <code class=\"gatsby-code-text\">mydata</code> são na verdade o mesmo objeto físico (apenas o valor interno do objeto mudou). Como as referências são triplamente iguais, fazer uma verificação de igualdade não nos diz se o valor mudou. A única solução possível seria ter criado uma cópia profunda dos dados e, posteriormente, fazer uma comparação profunda - mas isso pode ser proibitivamente caro para grandes estruturas de dados (especialmente aquelas com ciclos).</li>\n<li>O objeto <code class=\"gatsby-code-text\">mydata</code> pode conter referências para funções que capturaram variáveis dentro de clausuras. Não há como o React espiar dentro dessas clausuras e, portanto, não há como o React copiá-las e/ou verificar sua igualdade.</li>\n<li>O objeto <code class=\"gatsby-code-text\">mydata</code> pode conter referências a objetos que são re-instanciados durante uma re-renderização do pai (ou seja, não são triplamente igual) mas são conceitualmente iguais (ou seja, mesmas chaves e mesmos valores). Uma comparação profunda (cara) poderia detectar isso, exceto que as funções apresentam um problema novamente porque não há uma forma confiável para comparar duas funções para verificar se elas são semanticamente equivalentes.</li>\n</ul>\n<p>Dadas as restrições da linguagem, às vezes é impossível alcançarmos semânticas de igualdade significativas. Nesses casos, o React irá chamar <code class=\"gatsby-code-text\">componentWillReceiveProps</code> (mesmo que as props não tenham mudado) para que o componente tenha a oportunidade de examinar as novas props e agir de acordo.</p>\n<p>Como resultado, sua implementação do <code class=\"gatsby-code-text\">componentWillReceiveProps</code> NÂO DEVE assumir que suas props foram alteradas. Se você deseja que uma operação (como uma solicitação de rede) ocorra apenas quando props foram alteradas, o código do <code class=\"gatsby-code-text\">componentWillReceiveProps</code> precisa verificar se as props foram realmente alteradas.</p>","excerpt":"A documentação para  diz que  será invocado quando as props mudam como resultado de uma re-renderização. Algumas pessoas assumem que isso significa “se  é chamado, então as props devem ter mudado”, mas essa conclusão é logicamente incorreta. O princípio orientador é um dos meus favoritos da lógica/matemática formal: A implica B não implica B implica A Exemplo: “Se eu comer comida mofada, eu ficarei doente” não implica “se estou doente, então eu devo ter comido comida mofada”. Existem muitas…","frontmatter":{"title":"(A => B) !=> (B => A)","next":null,"prev":null,"author":[{"frontmatter":{"name":"Jim Sproch","url":"http://www.jimsproch.com"}}]},"fields":{"date":"08 de janeiro de 2016","path":"content/blog/2016-01-08-A-implies-B-does-not-imply-B-implies-A.md","slug":"/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html"}},"allMarkdownRemark":{"edges":[{"node":{"frontmatter":{"title":"React v17.0"},"fields":{"slug":"/blog/2020/10/20/react-v17.html"}}},{"node":{"frontmatter":{"title":"Apresentando o novo JSX Transform"},"fields":{"slug":"/blog/2020/09/22/introducing-the-new-jsx-transform.html"}}},{"node":{"frontmatter":{"title":"React v17.0 Candidato à lançamento: Sem novas funcionalidades"},"fields":{"slug":"/blog/2020/08/10/react-v17-rc.html"}}},{"node":{"frontmatter":{"title":"React v16.13.0"},"fields":{"slug":"/blog/2020/02/26/react-v16.13.0.html"}}},{"node":{"frontmatter":{"title":"Construindo Ótimas Experiências de Usuário com Modo Concorrente e Suspense"},"fields":{"slug":"/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html"}}},{"node":{"frontmatter":{"title":"Preparando para o Futuro com as Prereleases React"},"fields":{"slug":"/blog/2019/10/22/react-release-channels.html"}}},{"node":{"frontmatter":{"title":"Apresentando o novo React DevTools"},"fields":{"slug":"/blog/2019/08/15/new-react-devtools.html"}}},{"node":{"frontmatter":{"title":"React v16.9.0 e a atualização do Roadmap"},"fields":{"slug":"/blog/2019/08/08/react-v16.9.0.html"}}},{"node":{"frontmatter":{"title":"O React já esta traduzido? ¡Sí! Sim! はい！"},"fields":{"slug":"/blog/2019/02/23/is-react-translated-yet.html"}}},{"node":{"frontmatter":{"title":"React v16.8: O React com Hooks"},"fields":{"slug":"/blog/2019/02/06/react-v16.8.0.html"}}}]}},"pageContext":{"slug":"/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html"}},"staticQueryHashes":[]}