v19.2Latest

Mantendo Componentes Puros

Algumas funções JavaScript sãopuras.Funções puras apenas realizam um cálculo e nada mais. Ao escrever seus componentes estritamente como funções puras, você pode evitar toda uma classe de bugs confusos e comportamentos imprevisíveis à medida que sua base de código cresce. Para obter esses benefícios, no entanto, existem algumas regras que você deve seguir.

Você aprenderá
  • O que é pureza e como ela ajuda você a evitar bugs
  • Como manter componentes puros mantendo alterações fora da fase de renderização
  • Como usar o Modo Estrito para encontrar erros em seus componentes

Pureza: Componentes como fórmulas

Em ciência da computação (e especialmente no mundo da programação funcional),uma função puraé uma função com as seguintes características:

  • Ela cuida da sua própria vida.Ela não altera nenhum objeto ou variável que existia antes de ser chamada.
  • Mesmas entradas, mesma saída.Dadas as mesmas entradas, uma função pura deve sempre retornar o mesmo resultado.

Você já deve estar familiarizado com um exemplo de funções puras: fórmulas em matemática.

Considere esta fórmula matemática:y= 2x.

Sex= 2entãoy= 4. Sempre.

Sex= 3entãoy= 6. Sempre.

Sex= 3,ynão será às vezes9ou–1ou2.5dependendo da hora do dia ou do estado do mercado de ações.

Sey= 2x e x= 3,yserásempre 6.

Se fizéssemos disso uma função JavaScript, ela ficaria assim:

No exemplo acima,doubleé umafunção pura.Se você passar3, ela retornará6. Sempre.

O React é projetado em torno desse conceito.O React assume que todo componente que você escreve é uma função pura.Isso significa que os componentes React que você escreve devem sempre retornar o mesmo JSX dadas as mesmas entradas:

Quando você passadrinkers={2}paraRecipe, ele retornará JSX contendo2 cups of water. Sempre.

Se você passardrinkers={4}, ele retornará JSX contendo4 cups of water. Sempre.

Assim como uma fórmula matemática.

Você pode pensar em seus componentes como receitas: se você segui-las e não introduzir novos ingredientes durante o processo de cozimento, você obterá o mesmo prato todas as vezes. Esse "prato" é o JSX que o componente serve ao React pararenderizar.

Uma receita de chá para x pessoas: pegue x xícaras de água, adicione x colheres de chá e 0,5x colheres de especiarias, e 0,5x xícaras de leite

Ilustrado porRachel Lee Nabors

Efeitos Colaterais: consequências (não) intencionais

O processo de renderização do React deve sempre ser puro. Componentes devem apenasretornarseu JSX, e nãoalterarquaisquer objetos ou variáveis que existiam antes da renderização—isso os tornaria impuros!

Aqui está um componente que quebra essa regra:

Este componente está lendo e escrevendo uma variávelguestdeclarada fora dele. Isso significa quechamar este componente várias vezes produzirá JSX diferente!E mais, seoutroscomponentes leremguest, eles também produzirão JSX diferente, dependendo de quando foram renderizados! Isso não é previsível.

Voltando à nossa fórmulay= 2x, agora mesmo quex= 2, não podemos confiar quey= 4. Nossos testes poderiam falhar, nossos usuários ficariam perplexos, aviões cairiam do céu—você pode ver como isso levaria a bugs confusos!

Você pode corrigir este componentepassando guest como uma prop:

Agora seu componente é puro, pois o JSX que ele retorna depende apenas da propguest.

Em geral, você não deve esperar que seus componentes sejam renderizados em uma ordem específica. Não importa se você chamay= 2xantes ou depois dey= 5x: ambas as fórmulas serão resolvidas independentemente uma da outra. Da mesma forma, cada componente deve apenas "pensar por si mesmo" e não tentar coordenar ou depender de outros durante a renderização. Renderizar é como uma prova escolar: cada componente deve calcular o JSX por conta própria!

Deep Dive
Detectando cálculos impuros com o StrictMode

Mutação local: O segredinho do seu componente

No exemplo acima, o problema era que o componente alterou uma variávelpré-existentedurante a renderização. Isso é frequentemente chamado de"mutação"para soar um pouco mais assustador. Funções puras não mutam variáveis fora do escopo da função ou objetos que foram criados antes da chamada—isso as torna impuras!

No entanto,é completamente permitido alterar variáveis e objetos que vocêacabou decriar durante a renderização.Neste exemplo, você cria um array[], atribui-o a uma variávelcupse entãopushuma dúzia de copos nela:

Se a variávelcupsou o array[]fossem criados fora da funçãoTeaGathering, isso seria um grande problema! Você estaria alterando um objetopré-existenteao adicionar itens nesse array.

No entanto, está tudo bem porque você os crioudurante a mesma renderização, dentro deTeaGathering. Nenhum código fora deTeaGatheringjamais saberá que isso aconteceu. Isso é chamado de"mutação local"—é como o segredinho do seu componente.

Onde vocêpodecausar efeitos colaterais

Embora a programação funcional dependa fortemente da pureza, em algum momento, em algum lugar,algotem que mudar. Esse é meio que o objetivo da programação! Essas mudanças—atualizar a tela, iniciar uma animação, alterar os dados—são chamadas deefeitos colaterais.Eles são coisas que acontecem"por fora", não durante a renderização.

No React,efeitos colaterais geralmente pertencem dentro demanipuladores de eventos.Manipuladores de eventos são funções que o React executa quando você realiza alguma ação—por exemplo, quando você clica em um botão. Embora os manipuladores de eventos sejam definidosdentrodo seu componente, eles não são executadosdurantea renderização!Portanto, manipuladores de eventos não precisam ser puros.

Se você esgotou todas as outras opções e não consegue encontrar o manipulador de eventos certo para seu efeito colateral, você ainda pode anexá-lo ao JSX retornado com uma chamadauseEffectno seu componente. Isso diz ao React para executá-lo mais tarde, após a renderização, quando os efeitos colaterais são permitidos.No entanto, essa abordagem deve ser seu último recurso.

Quando possível, tente expressar sua lógica apenas com a renderização. Você ficará surpreso com o quão longe isso pode levá-lo!

Deep Dive
Por que o React se importa com pureza?

Recapitulação

  • Um componente deve ser puro, o que significa:
    • Ele cuida de seus próprios assuntos.Ele não deve alterar quaisquer objetos ou variáveis que existiam antes da renderização.
    • Mesmas entradas, mesma saída.Dadas as mesmas entradas, um componente deve sempre retornar o mesmo JSX.
  • A renderização pode acontecer a qualquer momento, então os componentes não devem depender da sequência de renderização uns dos outros.
  • Você não deve modificar (mutar) nenhuma das entradas que seus componentes usam para renderização. Isso inclui props, estado e contexto. Para atualizar a tela,"defina" o estadoem vez de modificar objetos preexistentes.
  • Procure expressar a lógica do seu componente no JSX que você retorna. Quando precisar "mudar coisas", geralmente você vai querer fazer isso em um manipulador de eventos. Como último recurso, você pode usaruseEffect.
  • Escrever funções puras exige um pouco de prática, mas desbloqueia o poder do paradigma do React.

Experimente alguns desafios

Challenge 1 of 3:Conserte um relógio quebrado #

Este componente tenta definir a classe CSS do <h1> para "night" durante o período da meia-noite às seis horas da manhã, e para "day" em todos os outros horários. No entanto, ele não funciona. Você pode consertar este componente?

Você pode verificar se sua solução funciona alterando temporariamente o fuso horário do computador. Quando a hora atual estiver entre meia-noite e seis da manhã, o relógio deve ter cores invertidas!