Primeiros passos com React Hooks — useContext.
Nessa série de artigos vamos falar sobre os novos hooks disponibilizados na versão ^16.8 do React.
1° Artigo: useState
2° Artigo: useEffect
3° Artigo: useReducer
Hoje o assunto é useContext!
Introdução
Um das principais motivações de trabalhar com React é a constante evolução em sua API. O time do Facebook trabalha incansavelmente para trazer constantes melhorias de performance e novas funcionalidades.
A nova API de contexto é prova disso, muito diferente da sua antecessora, ela traz uma forma desacopla de compartilhar estado entre os seus componentes React. Aqui vamos focar no uso dessa nova API com o hook useContext, se você quer mais detalhes da nova API de contexto deixarei os links de referencia no final do artigo.
Comparações
Poucos sabem mais o React já teve uma “API de contexto” antes da implementação dos hooks. O contexto era “embutido” no this do componente, que disponibilizava métodos auxiliares para acessar o mesmo.
A principal dificuldade em utilizar essa forma de contexto era gerenciar como ele era passado entre os componentes, por isso essa API nunca foi muito utilizada, sempre que havia necessidade de usar uma forma de “state global” optávamos por implementações como redux, effector, etc …
Aqui segue um exemplo simples de como era sua implementação
Note que dentro do componente MessageList temos o método getChildContext
que define o contexto que será passado para os filhos, childContextTypes
e contextTypes
definem os tipos das propriedades esperadas dentro do contexto.
Dentro da nova API de contexto cada objeto context vem com dois componentes Provider
e Consumer;
permite componentes consumidores assinarem mudanças no contexto.
ProviderConsumer
é utilizado nos componentes que precisam consumir o valor daquele contexto.
Está segregação nos permite utilizar o Consumer
só nos componentes que terão necessidade de consumir aquele contexto.
Nota, um consumidor já mais altera o estado do contexto, se você tem componentes alinhados que precisam atualizar o contexto a partir de componentes filhos, você pode passar uma função dentro do contexto permitindo que, componentes filhos atualizem o contexto (o exemplo abaixo mostra essa implementação).
Vou deixar um exemplo simples de como utilizar a nova API (deixei alguns comentários no código para mostrar o passo a passo).
Resultado:
O componente ThemeProvider implementa ThemeContext.Provider e define o estado inicial desse contexto.
No App instanciámos o componente ThemeProvider que prove o contexto para toda sua sub arvore, no componente Content (nesse caso único consumidor desse contexto) implementamos ThemeContext.Consumer.
Note também que dentro do componente ThemeProvider adicionamos o método toggleTheme que atualizar o estado de theme. O componente AppBar não necessita de nenhuma informação do contexto então não temos que nos preocupar em implementar nada adicional.
Usando a nova API de contexto é importante saber que toda vez que o estado do contexto for atualizado toda sua sub arvore será renderizada.
useContext
É o hook que vai te ajudar a trabalhar com a nova API de contexto.
UseContext funciona como um consumir, ele assina as alterações do contexto e apenas tem acesso a leitura. Todo o componente que chama useContext será renderizado quando alguma informação do contexto for atualizada.
No exemplo acima o componente Content usa ThemeContext.Consumer para consumir o contexto, vamos modificar ele e utilizar useContext.
Notaram a diferença?
Agora a única coisa que precisamos fazer foi chamar useContext passando o contexto como parâmetro. Isso faz com que o componente Content assina todas as atualização do contexto.
Utilizar useContext facilita a forma como você consume informações do contexto, mais o uso do Provider ainda é necessário acima da árvore para fornecer o valor do contexto.
Nem tudo são flores …
Antes de implementar um contexto na sua aplicação é necessário uma boa avaliação, pois se não for bem implementado pode acoplar seus componentes. O contexto não deve estar no nível dos componentes que serão reutilizados, pense nisso como uma forma de evitar a dependência de propriedades que venham do contexto.
Pense no contexto como uma forma de compartilhar informações “globais” da sua aplicação. Use com moderação rss.
Conclusão
Quando falamos em contexto useContext é uma forma simples e fácil de criar um consumidor para seus componentes React.
A nova API de contexto pode substituir toda aquela implementação do Redux, mais é importante ter em mente que toda a implementação de contexto deve ser bem avaliada antes de aplicada.
Você pode ainda combinar o uso da API de contexto com redutores e criar um “state global” fácil de gerenciar e simples de implementar (assunto para um próximo artigo).
No próximo artigo da série vamos falar um pouco sobre useMemo
e useCallback
.
Referencias:
Context API: https://pt-br.reactjs.org/docs/context.html
Old Context API: https://reactjs.org/docs/context.html#legacy-api
Hooks faq: https://reactjs.org/docs/hooks-faq.html