Context API: como usar de forma simples e fácil

Por Luis Pereira|
Atualizado: Jul 2023 |
Publicado: Abr 2021

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

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:
react context

Quer ver mais conteúdos como esse?

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:

estrutura de pastas 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:

arquivo em src/context/user/index.tsx

Entendendo o UserContext 

Quando criamos um contexto através do createContext, podemos observar que recebemos 3 parâmetros no de retorno:

arquivo em src/context/user/index.tsx
  • 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.

arquivo em src/context/user/index.tsx

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.

src/context/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

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!
Entre Chaves

Quer saber mais?