Estado: A Memória de um Componente
Os componentes frequentemente precisam alterar o que é exibido na tela como resultado de uma interação. Digitar em um formulário deve atualizar o campo de entrada, clicar em "próximo" em um carrossel de imagens deve mudar qual imagem é exibida, clicar em "comprar" deve colocar um produto no carrinho de compras. Os componentes precisam "lembrar" de coisas: o valor de entrada atual, a imagem atual, o carrinho de compras. No React, esse tipo de memória específica do componente é chamada deestado.
Você aprenderá
- Como adicionar uma variável de estado com o HookuseState
- Qual par de valores o Hook
useStateretorna - Como adicionar mais de uma variável de estado
- Por que o estado é chamado de local
Quando uma variável comum não é suficiente
Aqui está um componente que renderiza uma imagem de uma escultura. Clicar no botão "Próximo" deve mostrar a próxima escultura alterando oindexpara1, depois2, e assim por diante. No entanto, issonão funcionará(você pode tentar!):
O manipulador de eventohandleClickestá atualizando uma variável local,index. Mas duas coisas impedem que essa mudança seja visível:
- Variáveis locais não persistem entre renderizações.Quando o React renderiza este componente uma segunda vez, ele o renderiza do zero—não considera quaisquer mudanças nas variáveis locais.
- Mudanças em variáveis locais não disparam renderizações.O React não percebe que precisa renderizar o componente novamente com os novos dados.
Para atualizar um componente com novos dados, duas coisas precisam acontecer:
- Reteros dados entre renderizações.
- Acionaro React para renderizar o componente com novos dados (re-renderização).
O HookuseStatefornece essas duas coisas:
- Umavariável de estadopara reter os dados entre renderizações.
- Umafunção setter de estadopara atualizar a variável e acionar o React para renderizar o componente novamente.
Adicionando uma variável de estado
Para adicionar uma variável de estado, importeuseStatedo React no topo do arquivo:
Em seguida, substitua esta linha:
por
indexé uma variável de estado esetIndexé a função setter.
A sintaxe[ e ]aqui é chamada dedesestruturação de arraye permite que você leia valores de um array. O array retornado poruseStatesempre tem exatamente dois itens.
É assim que eles funcionam juntos emhandleClick:
Agora clicar no botão “Próximo” alterna a escultura atual:
Conheça seu primeiro Hook
No React,useState, assim como qualquer outra função que começa com “use”, é chamada de Hook.
Hookssão funções especiais que estão disponíveis apenas enquanto o React estárenderizando(o que vamos detalhar mais na próxima página). Eles permitem que você “se conecte” a diferentes funcionalidades do React.
Estado é apenas uma dessas funcionalidades, mas você conhecerá os outros Hooks mais tarde.
Armadilha
Hooks—funções que começam comuse—só podem ser chamados no nível superior dos seus componentes oudos seus próprios Hooks.Você não pode chamar Hooks dentro de condições, loops ou outras funções aninhadas. Hooks são funções, mas é útil pensar neles como declarações incondicionais sobre as necessidades do seu componente. Você “usa” funcionalidades do React no topo do seu componente, de forma similar a como você “importa” módulos no topo do seu arquivo.
Anatomia douseState
Quando você chamauseState, você está dizendo ao React que quer que este componente lembre de algo:
Neste caso, você quer que o React lembre doindex.
Observação
A convenção é nomear este par comoconst [something, setSomething]. Você pode nomeá-lo como quiser, mas convenções facilitam a compreensão entre projetos.
O único argumento parauseStateé ovalor inicialda sua variável de estado. Neste exemplo, o valor inicial doindexé definido como0comuseState(0).
Toda vez que seu componente renderiza,useStatefornece um array contendo dois valores:
- A variável de estado(
index) com o valor que você armazenou. - A função de atualização de estado(
setIndex) que pode atualizar a variável de estado e acionar o React para renderizar o componente novamente.
Veja como isso acontece na prática:
- Seu componente renderiza pela primeira vez.Como você passou
0parauseStatecomo o valor inicial paraindex, ele retornará[0, setIndex]. O React lembra que0é o valor de estado mais recente. - Você atualiza o estado.Quando um usuário clica no botão, ele chama
setIndex(index + 1).indexé0, então ésetIndex(1). Isso diz ao React para lembrar queindexagora é1e aciona outra renderização. - A segunda renderização do seu componente.O React ainda vê
useState(0), mas como o Reactlembraque você definiuindexcomo1, ele retorna[1, setIndex]em vez disso. - E assim por diante!
Dando a um componente múltiplas variáveis de estado
Você pode ter quantas variáveis de estado de quantos tipos quiser em um componente. Este componente tem duas variáveis de estado, um númeroindexe um booleanoshowMoreque é alternado quando você clica em “Mostrar detalhes”:
É uma boa ideia ter múltiplas variáveis de estado se seus estados forem não relacionados, comoindex e showMoreneste exemplo. Mas se você perceber que frequentemente altera duas variáveis de estado juntas, pode ser mais fácil combiná-las em uma. Por exemplo, se você tem um formulário com muitos campos, é mais conveniente ter uma única variável de estado que contém um objeto do que uma variável de estado por campo. LeiaEscolhendo a Estrutura do Estadopara mais dicas.
O estado é isolado e privado
O estado é local a uma instância de componente na tela. Em outras palavras,se você renderizar o mesmo componente duas vezes, cada cópia terá um estado completamente isolado!Alterar um deles não afetará o outro.
Neste exemplo, o componenteGalleryanterior é renderizado duas vezes sem alterações em sua lógica. Tente clicar nos botões dentro de cada uma das galerias. Observe que seus estados são independentes:
É isso que diferencia o estado das variáveis regulares que você pode declarar no topo do seu módulo. O estado não está vinculado a uma chamada de função específica ou a um local no código, mas é "local" ao local específico na tela. Você renderizou dois componentes<Gallery />, então seus estados são armazenados separadamente.
Observe também como o componentePagenão "sabe" nada sobre o estado doGalleryou mesmo se ele tem algum. Ao contrário das props,o estado é totalmente privado ao componente que o declara.O componente pai não pode alterá-lo. Isso permite que você adicione estado a qualquer componente ou o remova sem afetar o restante dos componentes.
E se você quisesse que ambas as galerias mantivessem seus estados sincronizados? A maneira correta de fazer isso no React éremovero estado dos componentes filhos e adicioná-lo ao seu pai compartilhado mais próximo. As próximas páginas se concentrarão em organizar o estado de um único componente, mas retornaremos a este tópico emCompartilhando Estado Entre Componentes.
Recapitulação
- Use uma variável de estado quando um componente precisa "lembrar" de alguma informação entre renderizações.
- Variáveis de estado são declaradas chamando o Hook
useState. - Hooks são funções especiais que começam com
use. Eles permitem que você "se conecte" a funcionalidades do React, como o estado. - Hooks podem lembrá-lo de imports: eles precisam ser chamados incondicionalmente. Chamar Hooks, incluindo
useState, só é válido no nível superior de um componente ou de outro Hook. - O Hook
useStateretorna um par de valores: o estado atual e a função para atualizá-lo. - Você pode ter mais de uma variável de estado. Internamente, o React as combina pela ordem.
- O estado é privado para o componente. Se você o renderizar em dois lugares, cada cópia terá seu próprio estado.
Try out some challenges
Challenge 1 of 4:Complete the gallery #
When you press “Next” on the last sculpture, the code crashes. Fix the logic to prevent the crash. You may do this by adding extra logic to event handler or by disabling the button when the action is not possible.
After fixing the crash, add a “Previous” button that shows the previous sculpture. It shouldn’t crash on the first sculpture.
