🧩 Exercícios: Context API e Criação de Custom Hooks
🧩 Exercícios Práticos: Context API e Criação de Custom Hooks
Spec Frontend Com React • Trilha Progressiva em 4 Níveis
🎯 Nível 1: Fundamentos
Problema 08.1 — Criação de Contexto Tipado com createContext
Contexto: Criação de Contexto Tipado com createContext no contexto de Context API e Criação de Custom Hooks.
Requisitos de Execução:
- Criar
ThemeContextcom valoreslightedarke função de alternânciatoggleTheme.
Resultado Esperado
Contexto de tema criado e tipado com TypeScript.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_08_1_SeuNome - Envie na tarefa:
Atividade Cap 08 - Context API e Criação de Custom Hooks
🔑 Gabarito de Código & Solução Comentada
// ThemeContext.tsx
import React, { createContext, useState, ReactNode } from 'react';
type Theme = 'light' | 'dark';
interface ThemeContextType { theme: Theme; toggleTheme: () => void; }
export const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
export const ThemeProvider = ({ children }: { children: ReactNode }) => {
const [theme, setTheme] = useState<Theme>('light');
const toggleTheme = () => setTheme(t => t === 'light' ? 'dark' : 'light');
return <ThemeContext.Provider value={{ theme, toggleTheme }}>{children}</ThemeContext.Provider>;
};
🔍 Nível 2: Prática
Problema 08.2 — Custom Hook useTheme com Validação Defensiva
Contexto: Custom Hook useTheme com Validação Defensiva no contexto de Context API e Criação de Custom Hooks.
Requisitos de Execução:
- Criar hook
useTheme()que lance exceção explicativa se usado fora de um<ThemeProvider>.
Resultado Esperado
Hook consumido no componente de toggle de tema.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_08_2_SeuNome - Envie na tarefa:
Atividade Cap 08 - Context API e Criação de Custom Hooks
🔑 Gabarito de Código & Solução Comentada
// useTheme.ts
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';
export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme deve ser utilizado dentro de um <ThemeProvider>');
}
return context;
};
⚡ Nível 3: Integração
Problema 08.3 — Custom Hook useLocalStorage com Sincronização entre Abas
Contexto: Custom Hook useLocalStorage com Sincronização entre Abas no contexto de Context API e Criação de Custom Hooks.
Requisitos de Execução:
- Implementar hook
useLocalStorage(key, initialValue)escutando eventos destoragedo navegador.
Resultado Esperado
Dados sincronizados no LocalStorage e atualizados automaticamente entre abas.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_08_3_SeuNome - Envie na tarefa:
Atividade Cap 08 - Context API e Criação de Custom Hooks
🔑 Gabarito de Código & Solução Comentada
// useLocalStorage.ts
import { useState, useEffect } from 'react';
export function useLocalStorage<T>(key: string, initial: T) {
const [value, setValue] = useState<T>(() => {
const saved = localStorage.getItem(key);
return saved ? JSON.parse(saved) : initial;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue] as const;
}
🏆 Nível 4: Desafio Corporativo
Problema 08.4 — Separação de Contextos de Estado e Despacho para Evitar Re-renders
Contexto: Separação de Contextos de Estado e Despacho para Evitar Re-renders no contexto de Context API e Criação de Custom Hooks.
Requisitos de Execução:
- Dividir
AuthContextemAuthStateContexteAuthDispatchContextotimizando a árvore de componentes.
Resultado Esperado
Re-renderizações desnecessárias eliminadas em componentes que apenas disparam ações.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_08_4_SeuNome - Envie na tarefa:
Atividade Cap 08 - Context API e Criação de Custom Hooks
🔑 Gabarito de Código & Solução Comentada
// SplitContext.tsx
import React, { createContext, useContext, useReducer, ReactNode } from 'react';
const StateCtx = createContext<any>(null);
const DispatchCtx = createContext<any>(null);
export const SplitProvider = ({ children }: { children: ReactNode }) => {
const [state, dispatch] = useReducer((s: any) => s, {});
return (
<StateCtx.Provider value={state}>
<DispatchCtx.Provider value={dispatch}>{children}</DispatchCtx.Provider>
</StateCtx.Provider>
);
};