Este projeto é um exercício prático sobre a React Context API, uma abordagem poderosa para compartilhar estado entre componentes sem necessidade de "prop drilling".
Prop drilling é o padrão de React de passar dados através de um grande número de componentes. Quando uma propriedade precisa ser passada através de múltiplas camadas de componentes intermediários (que não a utilizam), isso resulta em:
- Código mais inchado e difícil de entender
- Componentes intermediários sendo renderizados desnecessariamente
React Context permite criar um estado compartilhado que qualquer componente, em qualquer área da aplicação, pode acessar e utilizar.
Ao finalizar este projeto, você terá aprendido:
- Como React Context fornece compartilhamento de estado entre componentes
- Como criar um contexto para prover um valor a componentes filhos
- Como consumir valores de contexto usando
useContext() - Como atualizar valores de contexto a partir de componentes filhos
- Como estruturar provedores aninhados para o mesmo tipo de contexto
src/
├── App.jsx # Componente principal
├── index.jsx # Ponto de entrada
├── App.css # Estilos
├── components/
│ ├── ContactItem.jsx # Item individual de contato
│ ├── ContactsList.jsx # Lista de contatos
│ ├── ContactsSection.jsx # Seção de contatos
│ └── ThemeSwitcher.jsx # Alternador de tema
└── context/
└── ThemeContext.js # Context do tema
Objetivo: Eliminar prop drilling da prop theme
-
Criar o Context em
ThemeContext.js:const ThemeContext = React.createContext();
-
Envolver App com Provider em
index.jsx:- Importe
ThemeContext - Envolva
<App />com<ThemeContext.Provider value="light">
- Importe
-
Consumir em ContactItem:
- Remova a prop
themedos parâmetros - Use
const theme = useContext(ThemeContext); - Remova o prop drilling em
ContactsListeContactsSection
- Remova a prop
Objetivo: Usar diferentes temas para diferentes seções
- Em
App.jsx, envolva cada<ContactsSection>com seu próprio<ThemeContext.Provider> - Defina um Provider com
value="light"e outro comvalue="dark"
Objetivo: Criar um componente wrapper para o Provider
-
Em
ThemeContext.js, crie um componenteThemeArea:export function ThemeArea({ children, initialTheme }) { return ( <ThemeContext.Provider value={initialTheme}> {children} </ThemeContext.Provider> ); }
-
Substitua os
ThemeContext.ProvideremApp.jsxporThemeArea
Objetivo: Permitir atualizações do estado de contexto
-
Em
ThemeArea, useuseState()para gerenciar o tema:const [theme, setTheme] = useState(initialTheme);
-
Passar um objeto como valor do Provider:
<ThemeContext.Provider value={{ theme, setTheme }}>
-
Criar
ThemeSwitcher.jsx:- Recupere
themeesetThemeusandouseContext() - Crie um botão que alterne entre "light" e "dark"
- Recupere
-
Adicionar à
ContactsSection:- Importe e renderize
ThemeSwitcherapós a tag<h2>
- Importe e renderize
Objetivo: Implementar contextos aninhados com tema raiz
-
Em
index.jsx:- Envolva
<App />com<ThemeArea initialTheme="light">
- Envolva
-
Em
App.jsx:- Importe
ThemeContexteuseContext - Recupere o tema:
const theme = useContext(ThemeContext); - Aplique à div:
className={theme-${theme}} - Importe e renderize
ThemeSwitcherapós<h1>
- Importe
Cria um objeto Context que disponibiliza uma propriedade .Provider.
Componente que fornece um valor (value) acessível a componentes filhos.
Recupera o valor fornecido pelo Provider mais próximo na árvore de componentes.
Quando o Context fornece um objeto:
<ThemeContext.Provider value={{ theme, setTheme }}>
// Consumidor extrai valores
const { theme, setTheme } = useContext(ThemeContext);Componentes podem usar o valor do Provider mais próximo na hierarquia.
- Use Context com moderação para valores que mudam com pouca frequência
- Context não é sempre a melhor solução; considere alternativas como Redux ou
useReducer - Evite criar múltiplos Providers aninhados sem necessidade
- Matenha os valores de Context simples e bem definidos
- React Context API - Documentação Oficial
- Quando usar Context
- Alternativas: Redux,
useReducer,zustand
- Context criado e exportado
- Provider envolvendo App em index.jsx
- ContactItem removido de prop drilling
- ContactsList removido de prop drilling
- ContactsSection removido de prop drilling
- Multiple Providers implementados (light/dark)
- ThemeArea wrapper criado
- useState() implementado em ThemeArea
- ThemeSwitcher criado e funcionando
- Nested Providers configurados
- Tema aplicado ao className da div principal
- Começa com prop drilling simples
- Evoluir para Context com Provider
- Implementar múltiplos Providers
- Adicionar estado reativo com
useState() - Finalizar com contextos aninhados
Desenvolvido como material educacional para aprender React Context API.