🧩 Exercícios: Efeitos Colaterais com useEffect e Cleanup
Spec Frontend Com React • Trilha Progressiva em 4 Níveis
🎯 Nível 1: Fundamentos
Problema 04.1 — Sincronização com o DOM e Array de Dependências
Contexto: Sincronização com o DOM e Array de Dependências no contexto de Efeitos Colaterais com useEffect e Cleanup.
Requisitos de Execução:
- Atualizar o
document.titleda página sempre que o contador de notificações for modificado.
Resultado Esperado
Título da aba do navegador sincronizado: '(3) Novas Notificações'.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_04_1_SeuNome - Envie na tarefa:
Atividade Cap 04 - Efeitos Colaterais com useEffect e Cleanup
🔑 Gabarito de Código & Solução Comentada
// PageTitleSync.tsx
import React, { useState, useEffect } from 'react';
export const NotificationBadge: React.FC = () => {
const [unreadCount, setUnreadCount] = useState(3);
useEffect(() => {
document.title = unreadCount > 0 ? `(${unreadCount}) Notificações` : 'Portal';
}, [unreadCount]);
return <button onClick={() => setUnreadCount(0)}>Marcar lidas</button>;
};
🔍 Nível 2: Prática
Problema 04.2 — Função de Limpeza (Cleanup) com Timers (setInterval)
Contexto: Função de Limpeza (Cleanup) com Timers (setInterval) no contexto de Efeitos Colaterais com useEffect e Cleanup.
Requisitos de Execução:
- Implementar cronômetro com
setIntervalgarantindo o cancelamento no cleanup comclearInterval.
Resultado Esperado
Timer em execução | Memória liberada ao desmontar o componente.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_04_2_SeuNome - Envie na tarefa:
Atividade Cap 04 - Efeitos Colaterais com useEffect e Cleanup
🔑 Gabarito de Código & Solução Comentada
// TimerCronometro.tsx
import React, { useState, useEffect } from 'react';
export const TimerCronometro: React.FC = () => {
const [segundos, setSegundos] = useState(0);
useEffect(() => {
const timerId = setInterval(() => {
setSegundos(prev => prev + 1);
}, 1000);
return () => clearInterval(timerId); // Cleanup
}, []);
return <div>Tempo decorrido: {segundos}s</div>;
};
⚡ Nível 3: Integração
Problema 04.3 — Cancelamento de Requisições HTTP com AbortController
Contexto: Cancelamento de Requisições HTTP com AbortController no contexto de Efeitos Colaterais com useEffect e Cleanup.
Requisitos de Execução:
- Disparar busca assíncrona no
useEffecte cancelar requisição pendente comcontroller.abort()caso o usuário digite rápido.
Resultado Esperado
Race conditions de rede evitadas com AbortController.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_04_3_SeuNome - Envie na tarefa:
Atividade Cap 04 - Efeitos Colaterais com useEffect e Cleanup
🔑 Gabarito de Código & Solução Comentada
// SearchAutocomplete.tsx
import React, { useState, useEffect } from 'react';
export const SearchAutocomplete: React.FC<{ query: string }> = ({ query }) => {
const [results, setResults] = useState<string[]>([]);
useEffect(() => {
const controller = new AbortController();
fetch(`/api/search?q=${encodeURIComponent(query)}`, { signal: controller.signal })
.then(res => res.json())
.then(data => setResults(data.items))
.catch(err => { if (err.name !== 'AbortError') console.error(err); });
return () => controller.abort();
}, [query]);
return <ul>{results.map((r, i) => <li key={i}>{r}</li>)}</ul>;
};
🏆 Nível 4: Desafio Corporativo
Problema 04.4 — Diferenciação entre useEffect e useLayoutEffect para Medições do DOM
Contexto: Diferenciação entre useEffect e useLayoutEffect para Medições do DOM no contexto de Efeitos Colaterais com useEffect e Cleanup.
Requisitos de Execução:
- Utilizar
useLayoutEffectpara medir a largura de um elemento antes do paint da tela, prevenindo flicker visual.
Resultado Esperado
Dimensões calculadas sincronamente antes da renderização na tela.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_04_4_SeuNome - Envie na tarefa:
Atividade Cap 04 - Efeitos Colaterais com useEffect e Cleanup
🔑 Gabarito de Código & Solução Comentada
// TooltipPosition.tsx
import React, { useState, useRef, useLayoutEffect } from 'react';
export const TooltipPosition: React.FC = () => {
const elRef = useRef<HTMLDivElement>(null);
const [width, setWidth] = useState(0);
useLayoutEffect(() => {
if (elRef.current) {
setWidth(elRef.current.getBoundingClientRect().width);
}
}, []);
return <div ref={elRef}>Largura: {width}px</div>;
};