Hooks | React
- Hooks | React
Quando você altera um state com useState (tipo setAlgo(...)) ou acontece algo dentro do useEffect, o React não renderiza a tela inteira, ele renderiza novamente apenas o(s) componente(s) afetado(s)
useState - Gerenciar estado
Sempre opte por utilizar o callback dentro:
const [step, setStep] = useState(1);
setStep((currentStep) => currentStep + 1);
Usando o React.StrictMode, o seState é chamado duas vezes pois a função do StrictMode é identificar algum bug. Issue do GitHUB: ISSUE
Permite adicionar o state do React a componentes funcionais.
const [contador, setContador] = useState(0);
// Uso: setContador(contador + 1)
Cuidados: Evite atualizações em loops ou callbacks sem dependências claras.
O setState do useState é assíncrono e as vezes demora para atualizar o valor

useEffect - Sistemas externos
Executa efeitos colaterais em componentes funcionais.
useEffect(() => {
document.title = `Você clicou ${contador} vezes`;
}, [contador]); // Depende do contador
Função de retorno
useEffect(() => { onRegister(tab) return () => onUnregister(tab) }, [tab, onRegister, onUnregister])
No useEffect, o return serve para retornar uma função de “limpeza” (cleanup).
Essa função é executada em dois momentos:
- Antes do effect rodar de novo (quando alguma dependência muda)
- Quando o componente é desmontado (sai da tela)
Exemplo mental
Se tab mudar de "home" para "profile":
- cleanup do antigo:
onUnregister("home") - novo effect:
onRegister("profile")
Ou seja: o return garante que você desfaça efeitos anteriores, evitando “lixo” ou registros duplicados.
Cuidados: Limpe listeners ou subscrições para evitar vazamentos de memória.

useContext - Passar informações através de contexto
Acessa dados de um contexto React, facilitando o compartilhamento de dados entre componentes.
const tema = useContext(TemaContext);
Cuidados: Use com moderação para não causar rerenderizações desnecessárias.

useReducer - Gerenciar estado
Alternativa ao useState para estados complexos ou lógica de atualização.
const [estado, dispatch] = useReducer(reducer, estadoInicial);
Cuidados: Mantenha a função reducer pura e previsível.

Usar quando se há muitos estados em um componente. Abaixo há um exemplo

// useInfiniteScroll.ts
import { useReducer, useEffect } from "react";
import { paginationReducer, paginationInitialState } from "./paginationReducer";
type FetchData<T> = (page: number) => Promise<{ data: T[]; hasMore: boolean }>;
export function useInfiniteScroll<T>(fetchData: FetchData<T>) {
const [state, dispatch] = useReducer(paginationReducer, paginationInitialState);
const loadInitialData = async () => {
if (state.isLoading) return;
dispatch({ type: "FETCH_START" });
try {
const { data, hasMore } = await fetchData(1);
dispatch({ type: "FETCH_SUCCESS", payload: { data, hasMore } });
} catch (error) {
dispatch({ type: "FETCH_ERROR", payload: error.message });
}
};
const loadNextPage = async () => {
if (state.isPaginationLoading || !state.hasMore) return;
dispatch({ type: "FETCH_PAGINATION_START" });
try {
const { data, hasMore } = await fetchData(state.currentPage);
dispatch({ type: "FETCH_SUCCESS", payload: { data, hasMore } });
} catch (error) {
dispatch({ type: "FETCH_ERROR", payload: error.message });
}
};
useEffect(() => {
loadInitialData();
}, []);
return { ...state, loadNextPage };
}
useCallback - Performance
É utilizado para memorizar uma função callback em si, ao invés do valor retornado por ela. Isso significa que a função não será recriada a cada renderização, a menos que uma de suas dependências mude
const memoizadoCallback = useCallback(() => {
console.log(valor);
}, [valor]); // Depende do valor
Cuidados: Use apenas quando necessário para otimização, pode causar overhead.
useMemo - Performance
É utilizado para memorizar o valor retornado por uma função. Ele re-executa a função e recalcula o valor memorizado apenas quando uma das dependências muda.
const valorMemoizado = useMemo(() => calcularValor(pesado), [pesado]);
Cuidados: Semelhante ao useCallback, use para otimizações e evite overhead.

Important
- Use useMemo quando você deseja otimizar e armazenar em cache o resultado de uma computação que depende de certas entradas.
- Use useCallback quando você deseja otimizar a criação de funções callback que são passadas para componentes filhos.
useRef - Referencia de HTML
Persiste valores entre renders sem causar uma nova renderização.
const meuRef = useRef(initialValue);
Cuidados: Útil para referências a elementos DOM e armazenar valores mutáveis.

useImperativeHandle
Personaliza o valor da instância exposta ao usar ref em um componente pai.
useImperativeHandle(ref, () => ({
focus: () => {
meuInputRef.current.focus();
}
}));
Cuidados: Use com parcimônia, pois pode quebrar o fluxo de dados usual do React.
useLayoutEffect
Idêntico ao useEffect, mas dispara de forma síncrona após todas as mutações DOM.
useLayoutEffect(() => {
textareaRef.current.focus();
}, []);
Cuidados: Pode causar problemas de desempenho se usado excessivamente.

useDebugValue
Pode ser usado para exibir um label para hooks personalizados no React DevTools.
useDebugValue(valor > 5 ? "Muito alto" : "Baixo");
Cuidados: Principalmente para fins de desenvolvimento.
