0Pricing
React Academy · Aula

Tipando contextos e hooks personalizados

Crie contextos tipados com valores padrão e escreva hooks personalizados com tipos de retorno explícitos.

Tipando contextos e hooks personalizados é uma aula grátis de React Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de React Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de React Academy inclui 4 aulas no total.

Contexto tipado com createContext

Passe o tipo do contexto e um valor padrão para createContext. Use null como padrão quando o contexto precisar ser usado dentro de um provedor e trate esse caso com uma verificação.

interface AuthContextType {
  user: User | null;
  login: (credentials: Credentials) => Promise<void>;
  logout: () => void;
}

const AuthContext = createContext<AuthContextType | null>(null);

Padrão de gancho de proteção

Crie um gancho personalizado que leia o contexto e lance um erro se for usado fora do provedor. Isso elimina verificações de nulo em cada ponto de chamada.

export function useAuth(): AuthContextType {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error('useAuth must be used within AuthProvider');
  return ctx;
}

Definindo o tipo do provedor

O componente provedor envolve os elementos filhos e fornece o valor do contexto. Defina explicitamente o tipo do objeto de valor para que o TypeScript verifique se ele corresponde ao tipo do contexto.

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<User | null>(null);

  const login = async (creds: Credentials) => {
    const u = await apiLogin(creds);
    setUser(u);
  };

  const logout = () => setUser(null);

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

Contexto com valor padrão

Quando existir um padrão adequado, como um tema, passe-o diretamente para createContext para que o contexto nunca seja nulo e nenhum gancho de proteção seja necessário.

interface ThemeContextType { theme: 'light' | 'dark'; toggle: () => void; }

const ThemeContext = createContext<ThemeContextType>({
  theme: 'light',
  toggle: () => {},
});

export const useTheme = () => useContext(ThemeContext);

Definindo os valores de retorno de ganchos personalizados

Anote explicitamente o tipo de retorno dos ganchos personalizados ou deixe o TypeScript inferi-lo. Tipos explícitos servem como documentação e impedem alterações acidentais na estrutura.

interface UseCounterReturn {
  count: number;
  increment: () => void;
  decrement: () => void;
  reset: () => void;
}

function useCounter(initial = 0): UseCounterReturn {
  const [count, setCount] = useState(initial);
  return {
    count,
    increment: () => setCount(c => c + 1),
    decrement: () => setCount(c => c - 1),
    reset: () => setCount(initial),
  };
}

Tipos de retorno de tupla

Ganchos que retornam um par, como useState, usam tuplas. Defina seus tipos com as const ou com um tipo de tupla explícito para que a desestruturação seja inferida corretamente.

function useToggle(initial = false): [boolean, () => void] {
  const [value, setValue] = useState(initial);
  const toggle = useCallback(() => setValue(v => !v), []);
  return [value, toggle];
}

// Destructuring correctly infers types:
const [isOpen, toggleOpen] = useToggle();

Ganchos personalizados genéricos

Ganchos personalizados também podem ser genéricos. Um gancho genérico useLocalStorage armazena qualquer tipo serializável com segurança completa de tipos.

function useLocalStorage<T>(key: string, initialValue: T): [T, (val: T) => void] {
  const [stored, setStored] = useState<T>(() => {
    try {
      const item = localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch { return initialValue; }
  });

  const setValue = (val: T) => {
    setStored(val);
    localStorage.setItem(key, JSON.stringify(val));
  };

  return [stored, setValue];
}

Definindo o tipo de useReducer

Defina os tipos das ações como uniões discriminadas e a estrutura do estado como uma interface. O TypeScript garantirá tipos de ação válidos no redutor.

interface State { count: number; status: 'idle' | 'loading'; }
type Action =
  | { type: 'INCREMENT' }
  | { type: 'SET_STATUS'; payload: State['status'] };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case 'INCREMENT': return { ...state, count: state.count + 1 };
    case 'SET_STATUS': return { ...state, status: action.payload };
  }
}

const [state, dispatch] = useReducer(reducer, { count: 0, status: 'idle' });

Definindo o tipo de useCallback e useMemo

O TypeScript infere os tipos de useCallback e useMemo a partir da função de criação. Faça uma anotação explícita apenas quando a inferência falhar.

const handleChange = useCallback(
  (e: React.ChangeEvent<HTMLInputElement>) => {
    onChange(e.target.value);
  },
  [onChange]
);

const sorted = useMemo(
  () => [...items].sort((a, b) => a.name.localeCompare(b.name)),
  [items]
); // inferred as typeof items

Padrão de seletor de contexto com tipos

Um gancho seletor tipado recebe uma função seletora e retorna apenas a parte necessária, preservando a inferência completa de tipos.

function useAuthSelector<T>(selector: (ctx: AuthContextType) => T): T {
  const ctx = useAuth();
  return selector(ctx);
}

// Usage — TypeScript infers User | null:
const user = useAuthSelector(ctx => ctx.user);

Evitando any em ganchos

Nunca use any em ganchos personalizados. Use genéricos, unknown com verificações de tipo ou interfaces específicas para manter a cadeia de tipos intacta.

// Bad:
function useFetch(url: string): { data: any; loading: boolean } { ... }

// Good:
function useFetch<T>(url: string): { data: T | null; loading: boolean } {
  const [data, setData] = useState<T | null>(null);
  // ...
  return { data, loading };
}

Verificação rápida

Qual é a finalidade do padrão de gancho de proteção ao definir o tipo de um contexto do React?

Recapitulação

Defina o tipo do contexto com uma interface explícita e um gancho que proteja contra valores nulos. Anote os tipos de retorno de ganchos personalizados com interfaces ou tipos de tupla, use genéricos para ganchos reutilizáveis e defina o tipo de useReducer com ações de união discriminada para detectar despachos inválidos durante a compilação.

Perguntas Frequentes

A aula “Tipando contextos e hooks personalizados” é grátis?

Sim — o texto completo de “Tipando contextos e hooks personalizados” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de React Academy, atualize para CoddyKit PRO. O curso de React Academy inclui 4 aulas no total.

O que vou aprender em “Tipando contextos e hooks personalizados”?

Crie contextos tipados com valores padrão e escreva hooks personalizados com tipos de retorno explícitos. Você pratica React Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar React Academy?

Nenhuma experiência prévia é necessária. React Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Tipando contextos e hooks personalizados”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de React Academy?

Sim. Cada aula de React Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Tipando propriedades e tipos de retorno de componentes
  2. Tipando eventos e referências no TypeScript
  3. Componentes genéricos e tipos utilitários
  4. Tipando contextos e hooks personalizados
← Voltar para React Academy