Context API: como usar de forma simples e fácil
Neste artigo, vamos te mostrar o funcionamento da Context API para manipular estados globais da aplicação. Para isso, faremos uma aplicação pequena para demonstrar o comportamento da context api nos componentes filhos. Acompanhe!
Curte React e gostaria de saber mais sobre? Ouça esse episódio do Entre Chaves
Sumário
O que é a Context API?
Em uma aplicação típica do React, os dados são passados de cima para baixo (de pai para filho) via props, mas esse uso pode ser complicado para certos tipos de props (como preferências locais ou tema de UI), que são utilizadas por muitos componentes dentro da aplicação. Contexto (context) fornece a forma de compartilhar dados como esses, entre todos componentes da mesma árvore de componentes, sem precisar passar explicitamente props entre cada nível.
Ou seja, no uso básico do React, quando precisamos que um componente filho tenha ou manipule os dados do pai, precisamos informar esses dados e funções nas props do componente filhos. O que é bem simples na prática:
Porque o Context é útil?
Dependendo do contexto, o conceito de estado pode ficar complexo à medida que é necessário compartilhar o estado dentro da aplicação de uma forma global entre os componentes. Para isso, algumas bibliotecas surgiram para resolver essa nova demanda, como o Redux e MobEx. O Redux é a biblioteca mais utilizada para gerenciamento de estados.
O React context API é um gerenciador de estado global e é uma funcionalidade implementada a pouco tempo no ecossistema do React, podendo resolver 90% das soluções do Redux de forma extremamente simples.
Entendendo a Context API
À medida em que o projeto vai se tornando maior, os estados começam a ficar confusos e, possivelmente, a confundir nossa cabeça, tornando necessária a organização dos estados. Uma forma de fazer isso é por utilizar estados globais, de modo que os componentes possam acessar e manipular o estado global sem grandes problemas.
Quem nunca perdeu um bom tempo tentando entender de onde vêm e para onde vão os dados em nosso código? Junte-se ao time!!!
Uma das grandes alternativas é usar a biblioteca do Redux . Contudo, o Redux faz mais sentido à medida que a aplicação toma proporções gigantescas e complexas. Quando isso acontece, é necessário aplicar padrões de projeto para facilitar a manutenção do código — o que não tira nossa responsabilidade de aplicar padrões em projetos menores.
Vamos iniciar um projeto com npx do React
npx create-react-app context_api –template typescript
Estrutura do projeto:
Criando o Context
Para criar nosso context, vamos utilizar o hook: createContext diretamente da lib do react. Como estamos usando o Typescript, o compilador nos força a passar os tipos que iremos usar:
⦁ UserType: Tipos de dados que vão compor nosso estado global
⦁ PropsUserContext: São as props do nosso context, que terão um estado e uma função para modificar o state do tipo React.Dispatch .
⦁ DEFAULT_VALUE: O nosso valor default que passaremos para nosso context como parâmetro do hook createContext. Passamos o state com os dados zerados e uma função de inicialização.
Veja o código abaixo:
Entendendo o UserContext
Quando criamos um contexto através do createContext, podemos observar que recebemos 3 parâmetros no de retorno:
- Consumer : Um componente que assina as alterações de context. Isso permite que você assine um context dentro de um componente de função. Vamos substituí-lo pelo Hook useContext
- Provider: Ele proverá o context aos componentes filhos da árvore.
- displayName: Nos ajuda a melhor identificar o nome do context no devTools.
Agora, criaremos um componente React com nome de UserContextProvider: ele será responsável por retornar o componente UserContext com o seu Provider (portanto, UserContext.Provider ), que, por sua vez, envolverá os componentes filhos (children) da árvore do componente Pai. Esse componente receberá a propriedade value, o estado Global e a nossa função que modifica o estado.
Por fim, exportamos por default o UserContext para usá-lo a fim de capturar o estado do context utilizando o hook useContext. Depois disso, o exportamos para o componente UserContextProvider que irá envolver nossa aplicação.
Para utilizar o componente que criamos acima, geramos um arquivo na raiz da pasta src/context, chamado index.tsx.
O intuito desse arquivo é conter todos os contexts criados, que, no nosso caso, é apenas o UserContext.
Agora, vamos envolver a nossa aplicação com o nosso context global no arquivo App.tsx . Você pode observar que importamos o arquivo criado acima com o nome de GlobalContext e envolvemos toda a nossa aplicação. Dentro do meu arquivo App.tsx , eu tenho apenas o módulo das rotas da aplicação que você pode ver clicando AQUI.
Dentro desse módulo de rotas, teremos uma rota que usaremos para simular uma aplicação mais real.
Criando nossos componentes
Agora, criaremos os componentes que vão compor a nossa aplicação. A ideia é criar um componente Pai – a nossa tela de “form” e três componentes filhos: o ChildrenOne, ChildrenTwo e ChildrenThree.
O componente Pai terá um formulário para dar corpo à nossa aplicação, uma vez que os componentes filhos exibirão todo nosso context e poderão alterar apenas um item de nosso estado global, exemplo:
- ChildrenOne: Altera o nome.
- ChildrenTwo : Altera o sobrenome.
- ChildrenThree: Altera o e-mail.
Isso será interessante para observarmos o comportamento do context em cada um dos componentes filho.
Para poder estilizar os componentes, utilizamos a biblioteca do styled-components, devido a forma de estilização que ela usa:
Página Form
Vamos analisar o código abaixo:
Podemos observar que ocomponente FormData cria três estados com o hook useState do react, os quais servem para armazenar os dados de cada input.
Se observar na linha 21, estamos usando o hook useContext para trazer a função que vai alterar o nosso estado, dando um apelido para ela de setGlobalState.
Observe que definimos como parâmetro para o useContext o nosso context que estou exportando por default no arquivo src/context/user. Ele também retorna nosso estado, porém, não vamos usá-lo no componente Pai.
Esse é o código do nosso formulário que ficou oculto: três inputs que capturam o evento de onChange do input e alteram o estado local de acordo com o seu respectivo valor atribuído.
Sobre o componente filho:
Os componentes ChildrenOne, Two e Three é bem simples. Possui quase a mesma estrutura do nosso componente pai, no entanto, ele alterará apenas um campo do context global em cada componente.
Da mesma forma, importamos o hook useContext para resgatar a função de alteração do estado global e o estado global da aplicação.
Obs.: poderíamos passar o estado como props do componente, mas o intuito aqui é demostrar a utilização do estado global em diferentes componentes da árvore
Portanto, cada componente filho possui a mesma estrutura, possibilitando apenas a alteração de um campo por cada componente.
O resultado dessa sopa é a tela abaixo, com a qual você pode interagir e acessar clicando aqui.
Essa é a tela:
Vamos inserir algum dado no formulário e clicar no botão “Pronto”, para vermos a mágica acontecendo.
E veja que o estado foi refletido para todos os componentes num passe de mágica. (rs)!
Mesmo sendo uma aplicação bem simples, observamos a grande facilidade que o context API nos traz. Como foi digitado o e-mail errado, vamos alterar no componente filho 3 e…
Veja que refletiu nos demais componentes!
Fique à vontade para baixar o repositório e fazer seus próprios testes. À medida que sua aplicação estiver crescendo, recomendamos começar a observar os padrões de projeto que são utilizados, como duck pattner.
Conclusão
O Context Api do React substituirá o Redux? Essa é uma pergunta difícil.
De fato, há razões que sugerem que oContext API seja melhor que o Redux: ele está embutido no React e, portanto, você não precisa de dependências extras de terceiros — um pacote menor e melhor manutenção do projeto são o resultado. A API também é relativamente simples de usar quando você pega o jeito.
Recomendamos dar uma olhadinha nos seguintes artigos:
⦁ React Hooks vs. Redux: Do Hooks and Context replace Redux?
⦁ Context
Então galera, por hoje é só!
Trazemos mais informações técnicas em nosso podcast “Entre Chaves”. Clique aqui e dê o play!
Desenvolvimento de Software
Confira outros artigos
Testes end-to-end: sucesso na implementação da automação
Hoje, como você garante a entrega de valor, a confiabilidade e a eficiência do seu projeto? Com o intuito de responder a essa questão crucial, uma das melhores respostas é a automação de testes end-to-end. Muitas pessoas, principalmente nossos clientes, tendem a imaginar que automação de testes é apenas mais um tipo de teste de […]
Desenvolvimento de Software
Mecanismos de Acompanhamento no Desenvolvimento de Software
O uso de mecanismos de acompanhamento é imprescindível no mundo do desenvolvimento de software e pode potencializar a eficiência digital. O acompanhamento efetivo das operações é fundamental para garantir a entrega de soluções digitais de sucesso. Na nossa empresa, utilizamos uma metodologia única, o dti evolve, que incorpora inteligência artificial (IA) para acelerar nosso processo de […]
Desenvolvimento de Software
Eficiência digital com copilot: um caso de uso do GitHub
Em um mundo em constante evolução tecnológica, otimizar o tempo e potencializar a eficiência digital se torna cada vez mais crucial. Portanto, vamos apresentar alguns experimentos que estão sendo implementados com o Git Hub Copilot em busca de maior eficiência digital. Certamente quem nos acompanha sabe que estamos experimentando e introduzindo as melhores ferramentas de […]
Desenvolvimento de Software