useContext do React js

 


REACT.JS · GUIA PARA INICIANTES

Como funciona o useContext do React? Guia completo com exemplos práticos

Aprenda o que é o useContext do React, para que ele serve, como compartilhar informações entre componentes e como utilizá-lo passo a passo, com exemplos de código e explicações simples.

O que você vai aprender:
  • O que é o useContext e qual problema ele resolve.
  • Como criar e configurar um Context.
  • Como compartilhar dados entre componentes distantes.
  • Como criar um tema escuro e claro usando Context.
  • Quais erros evitar ao trabalhar com esse recurso.

1. O que é o useContext do React?

O useContext é um Hook do React que permite que um componente leia informações compartilhadas por outros componentes, sem precisar receber esses dados manualmente por todas as camadas intermediárias.

Mas, antes de entender o useContext, precisamos conhecer três peças importantes: componentes, props e Context.

O que são componentes?

Componentes são partes da interface de um site. Por exemplo, um site pode ter um cabeçalho, um menu, uma lista de produtos e um botão de compra. Cada parte pode ser construída como um componente React.

O que são props?

Props são informações enviadas de um componente pai para um componente filho. Imagine que o componente pai é uma pessoa entregando uma mensagem ao filho.

Exemplo 1 — Passando informações com props
function Saudacao(props) {
  return <h1>
    Olá, {props.nome}!
  </h1>;
}

function App() {
  return <Saudacao nome="Ana" />;
}

Como funciona:

  1. O componente App utiliza o componente Saudacao.
  2. App envia o texto "Ana" pela prop chamada nome.
  3. Saudacao recebe a informação e mostra "Olá, Ana!".

Esse método funciona muito bem. O problema aparece quando muitos componentes precisam compartilhar a mesma informação.

2. Qual problema o useContext resolve?

Imagine que você tem uma informação chamada nomeUsuario. O componente principal conhece essa informação, mas um componente bem distante precisa utilizá-la.

Sem Context, talvez você precise passar a informação por vários componentes que não precisam utilizá-la. Esse processo é conhecido como prop drilling.

Uma comparação simples:

Imagine que uma pessoa precisa entregar um bilhete a outra que está no fim de um corredor. Em vez de entregar diretamente, ela precisa passar o bilhete por cinco pessoas. Isso representa o prop drilling.

O Context funciona como um quadro de avisos compartilhado: os componentes que precisam da informação podem consultá-la diretamente, desde que estejam dentro do mesmo Provider.

Exemplo de prop drilling

Exemplo 2 — A informação passando por vários componentes
function App() {
  const nome = "Ana";

  return <Pagina nome={nome} />;
}

function Pagina({ nome }) {
  return <Painel nome={nome} />;
}

function Painel({ nome }) {
  return <Usuario nome={nome} />;
}

function Usuario({ nome }) {
  return <p>Olá, {nome}!</p>;
}

Perceba que Pagina e Painel apenas repassam nome. Eles não precisam usar o dado, mas são obrigados a recebê-lo e encaminhá-lo.

O useContext ajuda a evitar esse repasse desnecessário. Isso não significa que props sejam ruins: elas continuam sendo ótimas para informações específicas de um componente.

3. O que é Context no React?

Context é um recurso do React que permite compartilhar um valor com os componentes que estão dentro de uma determinada área da árvore de componentes.

Para utilizar esse recurso, normalmente precisamos de três elementos:

  1. createContext: cria o Context, que será usado para compartilhar o valor.
  2. Provider: disponibiliza o valor aos componentes que estão dentro dele.
  3. useContext: permite que um componente leia o valor disponibilizado.
Importante:

O Context não é o valor em si. Ele é o canal utilizado para disponibilizar o valor aos componentes descendentes. O Provider fornece o valor, e useContext permite lê-lo.

4. Como usar useContext passo a passo

Vamos construir um exemplo pequeno para entender o mecanismo antes de criar uma aplicação maior.

Passo 1 — Criar o Context

Primeiro, importamos createContext do React. Essa função cria um objeto Context que será utilizado para compartilhar informações.

src/UsuarioContext.jsx
import { createContext } from "react";

export const UsuarioContext =
  createContext(null);

Entendendo cada parte:

  • createContext cria o Context.
  • UsuarioContext é o nome que escolhemos para esse Context.
  • null é o valor padrão utilizado quando não existe um Provider correspondente acima do componente consumidor.
  • export permite importar esse Context em outros arquivos.

Usar null como valor padrão é uma escolha comum quando queremos deixar claro que o valor real deve ser fornecido por um Provider.

Passo 2 — Disponibilizar o valor com Provider

Agora vamos criar um componente principal que fornece o nome do usuário. Em versões atuais do React, podemos escrever <UsuarioContext value={"{...}"}>. A forma <UsuarioContext.Provider value={"{...}"}> também funciona e é útil para manter compatibilidade com versões anteriores.

src/App.jsx
import { UsuarioContext }
  from "./UsuarioContext";

import { Usuario }
  from "./Usuario";

export default function App() {
  const usuario = {
    nome: "Ana",
    idade: 25
  };

  return (
    <UsuarioContext.Provider
      value={usuario}
    >
      <Usuario />
    </UsuarioContext.Provider>
  );
}

Nesse exemplo, criamos um objeto chamado usuario. Ele contém duas informações: nome e idade.

Ao colocar Usuario dentro do Provider, disponibilizamos o objeto para os componentes descendentes que utilizarem esse Context.

Passo 3 — Ler o valor com useContext

Agora vamos criar o componente que precisa acessar os dados. Ele não precisa receber nome ou idade por props.

src/Usuario.jsx
import { useContext }
  from "react";

import { UsuarioContext }
  from "./UsuarioContext";

export function Usuario() {
  const usuario =
    useContext(UsuarioContext);

  return (
    <section>
      <h2>Perfil</h2>
      <p>
        Nome: {usuario.nome}
      </p>
      <p>
        Idade: {usuario.idade}
      </p>
    </section>
  );
}

O que acontece nesse código?

  1. Importamos useContext.
  2. Entregamos UsuarioContext ao useContext.
  3. O React procura o Provider correspondente mais próximo acima do componente.
  4. O valor encontrado é guardado na variável usuario.
  5. Usamos usuario.nome e usuario.idade para exibir os dados.
Resultado esperado:

Perfil

Nome: Ana

Idade: 25

Passo 4 — Entender a ligação entre os componentes

O caminho dos dados é simples: App fornece o objeto, o Provider o disponibiliza e Usuario o lê por meio de useContext.

App → cria o objeto usuario

Provider → disponibiliza o objeto

useContext → lê o valor do Context

Usuario → mostra os dados na tela

Você não precisa passar o objeto por cada componente intermediário. Essa é a principal vantagem desse exemplo.

5. Segundo exemplo prático: tema escuro e claro

Agora vamos aplicar a mesma ideia em uma situação comum: compartilhar a escolha de tema de uma aplicação.

Imagine um site com vários componentes. O cabeçalho, o menu e o painel precisam saber se o tema atual é escuro ou claro. O Context pode disponibilizar essa informação para todos eles.

Passo 1 — Criar o Context do tema

src/TemaContext.jsx
import { createContext }
  from "react";

export const TemaContext =
  createContext(null);

Passo 2 — Criar um estado para controlar o tema

O Context pode compartilhar valores, mas não cria sozinho uma maneira de alterá-los. Para isso, vamos utilizar outro Hook do React: useState.

O useState guarda um valor que pode mudar durante o funcionamento do componente. Aqui, ele guardará o tema atual.

src/App.jsx
import { useState }
  from "react";

import { TemaContext }
  from "./TemaContext";

import { Painel }
  from "./Painel";

export default function App() {
  const [tema, setTema] =
    useState("escuro");

  function alternarTema() {
    setTema(
      tema === "escuro"
        ? "claro"
        : "escuro"
    );
  }

  return (
    <TemaContext.Provider
      value={{
        tema: tema,
        alternarTema: alternarTema
      }}
    >
      <Painel />
    </TemaContext.Provider>
  );
}

Observe que o valor compartilhado agora é um objeto com duas propriedades:

  • tema: informa se o tema é escuro ou claro.
  • alternarTema: é uma função que muda o tema atual.

O Provider pode compartilhar tanto dados quanto funções. Isso permite que componentes consumidores leiam informações e solicitem alterações por meio das funções fornecidas.

Passo 3 — Consumir o Context no painel

src/Painel.jsx
import { useContext }
  from "react";

import { TemaContext }
  from "./TemaContext";

export function Painel() {
  const { tema, alternarTema } =
    useContext(TemaContext);

  const estilos = {
    backgroundColor:
      tema === "escuro"
        ? "#161b22"
        : "#ffffff",
    color:
      tema === "escuro"
        ? "#ffffff"
        : "#111111",
    padding: "24px"
  };

  return (
    <section style={estilos}>
      <h2>
        Tema: {tema}
      </h2>

      <button onClick={alternarTema}>
        Alternar tema
      </button>
    </section>
  );
}

Nesse componente, useContext recebe TemaContext. A desestruturação retira tema e alternarTema do objeto compartilhado.

Quando o usuário clica no botão, alternarTema muda o estado no componente App. O React atualiza a interface, e o consumidor passa a receber o valor atualizado do Context.

O que você acabou de aprender?

O Context pode compartilhar um valor simples, como um nome, ou um objeto com dados e funções, como o estado do tema e a função que o modifica.

6. Como o useContext funciona por trás dos panos?

Agora que você já viu os exemplos, vamos entender o que o React faz internamente, sem complicar.

  1. O componente pai renderiza: o React encontra o Provider e o valor que ele disponibiliza.
  2. O componente consumidor lê o Context: useContext recebe o objeto Context e encontra o Provider correspondente mais próximo na árvore acima dele.
  3. O componente recebe o valor: a variável retorna o valor atual fornecido por esse Provider.
  4. O valor muda: se o Provider fornecer um valor diferente, os componentes que utilizam aquele Context podem renderizar novamente.
  5. A interface é atualizada: o React compara o resultado da renderização e aplica as mudanças necessárias na tela.

O React compara os valores do Context usando a comparação Object.is. Quando o valor fornecido muda segundo essa comparação, os consumidores desse Context são atualizados.

Um detalhe importante:

Criar um Context não faz todos os componentes da aplicação receberem automaticamente seus dados. O componente precisa estar dentro do Provider correto e utilizar esse Context.

7. Qual é a diferença entre useContext e useState?

Esses dois Hooks têm funções diferentes, embora trabalhem juntos em muitas aplicações.

Recurso Para que serve? Exemplo
useState Guarda e atualiza o estado de um componente. Contador de cliques.
createContext Cria um Context para compartilhar valores. Contexto do usuário.
Provider Disponibiliza o valor do Context aos descendentes. Fornecer o tema atual.
useContext Lê o valor do Context no componente consumidor. Consultar o tema atual.

Pense assim: useState é como uma caixa que guarda um valor e permite trocá-lo. Context é como um canal pelo qual esse valor pode ser compartilhado. useContext é a maneira de consultar o canal.

8. Erros comuns ao usar useContext

Erro 1 — Esquecer o Provider

Se o Context foi criado com null como valor padrão e nenhum Provider correspondente envolve o consumidor, useContext pode retornar null.

Exemplo de problema
const usuario =
  useContext(UsuarioContext);

// Pode falhar se usuario for null:
return <p>
  {usuario.nome}
</p>;

Como resolver: verifique se o componente está dentro do Provider e se o Context importado é o correto.

Erro 2 — Confundir o Context com seu valor

O objeto criado por createContext não é automaticamente o objeto do usuário ou o tema. Você precisa ler o valor usando useContext.

Forma correta
const usuario =
  useContext(UsuarioContext);

Erro 3 — Alterar diretamente um objeto compartilhado

Não modifique diretamente um objeto de estado e espere que o React atualize a tela automaticamente.

Evite esta abordagem
// Não faça isso com um objeto de estado:
usuario.nome = "Carlos";

Em vez disso, utilize uma função de atualização do estado, como setUsuario, criando um novo objeto com os dados atualizados. O Context compartilhará o novo valor quando o Provider for atualizado.

Erro 4 — Esperar que o Context funcione fora do Provider

Um componente não consegue ler o valor de um Provider que está abaixo dele na árvore. O Provider correspondente precisa estar acima do componente consumidor.

Erro 5 — Criar um objeto novo a cada renderização sem necessidade

Se o Provider recebe um objeto novo em cada renderização, a identidade desse objeto muda. Isso pode provocar atualizações adicionais nos consumidores.

Em aplicações maiores, vale analisar a estrutura do estado e, quando necessário, utilizar técnicas como useMemo para estabilizar valores derivados. Não é necessário fazer isso em todos os casos.

9. Boas práticas para usar useContext

  • Compartilhe o que realmente é compartilhado: tema, idioma e dados do usuário são exemplos comuns.
  • Prefira props para dados locais: não crie Context para toda informação pequena.
  • Organize os Contexts: nomes como UsuarioContext e TemaContext deixam a finalidade clara.
  • Evite Contexts gigantes: agrupar informações sem relação pode fazer componentes receberem atualizações desnecessárias.
  • Crie funções de atualização claras: se os dados mudam, compartilhe funções que atualizem o estado corretamente.
  • Use TypeScript quando fizer sentido: os tipos podem ajudar a identificar valores ausentes ou incorretos durante o desenvolvimento.
  • Não confunda Context com armazenamento permanente: ele não salva os dados automaticamente após atualizar a página.

10. Quando devo usar useContext?

Use Context quando vários componentes precisam acessar a mesma informação e passá-la por props seria trabalhoso ou deixaria o código difícil de manter.

Situação Context é uma boa opção?
Compartilhar o tema do site. Sim.
Compartilhar o idioma da interface. Sim.
Enviar um título para um único componente filho. Geralmente, props são suficientes.
Compartilhar informações globais de uma aplicação. Pode ser uma boa opção, dependendo da necessidade.
Gerenciar sozinho um estado complexo com muitas regras. Talvez seja necessário complementar com outras soluções.

O Context faz parte do React e pode ser suficiente para muitos projetos. Bibliotecas de gerenciamento de estado podem ser úteis quando existem necessidades adicionais, mas não são obrigatórias para utilizar Context.

11. Exercício para praticar

Desafio: compartilhar o nome do usuário

Agora é sua vez de praticar. Crie um pequeno projeto React com três arquivos: UsuarioContext.jsx, App.jsx e Perfil.jsx.

  1. Crie UsuarioContext usando createContext.
  2. No App, disponibilize o nome "Pedro" por meio do Provider.
  3. Crie o componente Perfil.
  4. Dentro de Perfil, utilize useContext para ler o nome.
  5. Mostre a mensagem "Bem-vindo, Pedro!" na tela.

Resultado esperado: Bem-vindo, Pedro!

Desafio extra: compartilhe também a profissão do usuário e exiba as duas informações no componente Perfil.

12. Resumo: como funciona o useContext?

Vamos revisar as partes essenciais:

  • createContext: cria o Context.
  • Provider: disponibiliza o valor para os componentes descendentes.
  • useContext: lê o valor do Context no componente.
  • useState: pode guardar e atualizar os dados compartilhados.
  • Prop drilling: é o repasse de props por componentes intermediários que não precisam usar os dados.

A principal vantagem do useContext é permitir que componentes acessem informações compartilhadas sem precisar receber essas informações manualmente por todas as camadas intermediárias.

13. Conclusão

O useContext é um recurso importante do React para organizar aplicações que compartilham dados entre vários componentes. Ele é especialmente útil para temas, idiomas, informações de usuários e outras configurações utilizadas em diferentes partes da interface.

Para começar, lembre-se desta sequência: crie o Context, disponibilize o valor com um Provider e leia esse valor usando useContext. Depois, pratique com exemplos pequenos antes de aplicar o recurso em projetos maiores.

Compreender como essas peças trabalham juntas ajuda você a escrever componentes mais organizados e a entender melhor como o React compartilha informações.

RECURSO RECOMENDADO

Quer ampliar seus conhecimentos em programação?

Se você deseja continuar estudando desenvolvimento de software, conheça o curso Torne-se um Programador Fullstack e domine o mercado digital! e confira se o conteúdo combina com seus objetivos de aprendizado.

Antes de se inscrever, consulte a página do curso para verificar a grade curricular, as tecnologias ensinadas, as condições de acesso e o preço atual.

Conhecer o curso →

Transparência: este artigo contém um link de afiliado. Podemos receber uma comissão se você realizar uma compra por meio dele, sem custo adicional para você. A recomendação é complementar ao conteúdo educativo.


Comentários

Postagens mais visitadas deste blog

useMemo do React js

useEffect do React js

useState do React js