Debug de Aplicações React com Cursor: Ferramentas, Dicas e Fluxos

Debugar aplicações React pode ser desafiador devido à hierarquia de componentes, complexidade de gerenciamento de estado e fluxos de dados assíncronos. Com as ferramentas de debug integradas do Cursor e suporte de IA, você pode identificar e corrigir problemas mais rapidamente. Este guia aborda fluxos de trabalho específicos para debug React.
Pré-requisitos
Antes de começar, você precisará de:
- Cursor instalado (versão mais recente)
- Projeto React configurado
- Extensão React DevTools do navegador instalada (opcional mas recomendada)
Configurando o Debug no Cursor
Configuração de Launch
Crie .vscode/launch.json para debug React:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug React App",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}",
"sourceMapPathOverrides": {
"webpack:///src/*": "${webRoot}/src/*"
}
},
{
"name": "Debug Next.js",
"type": "node",
"request": "launch",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev"],
"env": {
"NODE_OPTIONS": "--inspect"
},
"console": "integratedTerminal"
}
]
}
Source Maps
Certifique-se de que source maps estão habilitados na configuração de build:
// vite.config.ts
export default defineConfig({
build: {
sourcemap: true,
},
});
// next.config.js
const nextConfig = {
productionBrowserSourceMaps: true,
};
module.exports = nextConfig;
Debug de Componentes React
Breakpoints em JSX
Defina breakpoints diretamente nos arquivos de componentes:
// src/components/UserProfile.tsx
import { useState, useEffect } from 'react';
export function UserProfile({ userId }: { userId: string }) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchUser() {
setLoading(true);
const response = await fetch(`/api/users/${userId}`);
// Defina breakpoint aqui
const data = await response.json();
setUser(data);
setLoading(false);
}
fetchUser();
}, [userId]);
if (loading) return <div>Loading...</div>;
if (!user) return <div>User not found</div>;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
Breakpoints Condicionais
Clique com o botão direito no breakpoint para definir uma condição:
Condition: userId === "12345"
O breakpoint só será acionado quando a condição for satisfeita.
Técnicas de Debug de Estado
Console Logging com Contexto
Use a IA do Cursor para adicionar logs estratégicos:
Adicione console.log para rastrear mudanças de estado neste componente
O Cursor adiciona:
useEffect(() => {
console.log('[UserProfile] userId changed:', userId);
async function fetchUser() {
console.log('[UserProfile] fetching user...');
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
console.log('[UserProfile] received data:', data);
setUser(data);
}
fetchUser();
}, [userId]);
Integração com React DevTools
O React DevTools roda no navegador, mas você pode referenciar dados de componentes no Cursor:
- Abra o React DevTools no navegador
- Inspecione a árvore de componentes
- Copie props/state do componente
- Cole no chat do Cursor para análise
Este componente está renderizando infinitamente. As props e state do DevTools são:
[Colar dados]
O que está causando o loop?
Resolvendo Problemas com Hooks
Dependências do useEffect
Problema comum: array de dependências incompleto ou incorreto.
// Before - buggy
useEffect(() => {
fetchData(query);
}, []); // Missing dependency
// After - fixed
useEffect(() => {
fetchData(query);
}, [query]); // Correct dependency
Peça ao Cursor para auditar seus hooks:
Revise todos os hooks useEffect neste arquivo para dependências ausentes
Debug de Hooks Customizados
// src/hooks/useLocalStorage.ts
import { useState, useEffect, useCallback } from 'react';
export function useLocalStorage<T>(key: string, initialValue: T) {
// Get stored value
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(`Error reading localStorage key "${key}":`, error);
return initialValue;
}
});
// Return a wrapped version of useState's setter function
const setValue = useCallback(
(value: T | ((val: T) => T)) => {
try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error(`Error setting localStorage key "${key}":`, error);
}
},
[key, storedValue]
);
return [storedValue, setValue] as const;
}
O Cursor pode detectar violações comuns das regras dos hooks, como chamar hooks condicionalmente ou dentro de loops. Use integração com linter para capturar cedo.
Debug de Next.js
Debug Server-Side
Debug de rotas de API e Server Components:
{
"name": "Debug Next.js Server",
"type": "node",
"request": "launch",
"runtimeExecutable": "npx",
"runtimeArgs": ["next", "dev"],
"env": {
"NODE_OPTIONS": "--inspect=9230"
},
"port": 9230
}
Breakpoints em Rotas de API
// app/api/users/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
// Defina breakpoint aqui
const users = await prisma.user.findMany();
// Inspecione users no debugger
return NextResponse.json({ users });
}
Client-Side vs Server-Side
| Contexto | Abordagem de Debug |
|---|---|
| Componentes Cliente | Chrome DevTools, React DevTools |
| Componentes Servidor | Node.js debugger do Cursor |
| Rotas de API | Node.js debugger |
| Middleware | Console logs + Node.js debugger |
Problemas Comuns do React e Soluções
Re-renderizações Infinitas
Sintoma: Navegador trava e logs repetidos aparecem no console.
// Problem: every render creates new object reference
function Parent() {
const [count, setCount] = useState(0);
return (
<Child config={{ limit: 10 }} /> // New object every render!
);
}
// Solution: memoize the config
function Parent() {
const [count, setCount] = useState(0);
const config = useMemo(() => ({ limit: 10 }), []);
return <Child config={config} />;
}
Closures Desatualizadas
// Problem: callback captures old state
function Counter() {
const [count, setCount] = useState(0);
const logCount = useCallback(() => {
console.log(count); // Always logs initial value
}, []); // Missing dependency
// Solution: use functional updates or include dependency
const logCountFixed = useCallback(() => {
console.log(count);
}, [count]);
}
Memory Leaks
// Problem: state update after unmount
useEffect(() => {
let isMounted = true;
fetchData().then(data => {
if (isMounted) {
setData(data);
}
});
return () => {
isMounted = false;
};
}, []);
Debug com IA do Cursor
Análise de Erros
Cole mensagens de erro no Cursor:
Estou recebendo este erro no meu app React:
"Cannot read properties of undefined (reading 'map')"
O código do componente é:
[Colar código]
O que está errado e como corrigir?
Debug de Performance
Este componente está renderizando lentamente. O código e a captura de tela do React DevTools Profiler são:
[Colar código]
Como posso otimizá-lo?
Otimizações comuns sugeridas pelo Cursor:
- Memoizar cálculos caros com
useMemo - Prevenir re-renderizações desnecessárias com
React.memo - Virtualizar listas longas
- Dividir componentes grandes
Debug de Gerenciamento de Estado
Redux DevTools
Configure Redux DevTools em desenvolvimento:
// store.ts
import { configureStore } from '@reduxjs/toolkit';
export const store = configureStore({
reducer: {
user: userReducer,
cart: cartReducer,
},
devTools: process.env.NODE_ENV !== 'production',
});
Inspeção de Store Zustand
// Debug Zustand store
import { useUserStore } from './stores/userStore';
// In browser console
const userStore = useUserStore.getState();
console.log(userStore);
Testando Componentes Antes do Debug
// src/components/__tests__/UserProfile.test.tsx
import { render, screen, waitFor } from '@testing-library/react';
import { UserProfile } from '../UserProfile';
describe('UserProfile', () => {
it('handles loading state', () => {
render(<UserProfile userId="1" />);
expect(screen.getByText('Loading...')).toBeInTheDocument();
});
it('handles error state', async () => {
render(<UserProfile userId="invalid" />);
await waitFor(() => {
expect(screen.getByText('User not found')).toBeInTheDocument();
});
});
});
Checklist de Debug
| Problema | O que Verificar Primeiro |
|---|---|
| Componente não renderiza | Retornos condicionais e estados de loading |
| Estado não atualiza | Chamadas setState e arrays de dependência |
| Props são undefined | Passagem de props do componente pai |
| Chamadas de API falham | Aba Network e Error Boundaries |
| Performance lenta | Re-renderizações desnecessárias |
| Erros de tipo | Interfaces TypeScript correspondem aos dados |
Atalhos de Teclado para Debug
| Ação | Atalho |
|---|---|
| Alternar breakpoint | F9 |
| Iniciar debug | F5 |
| Step over | F10 |
| Step into | F11 |
| Step out | Shift + F11 |
| Continuar | F5 |
| Abrir console de debug | Ctrl + Shift + Y |
Recursos Relacionados
Última atualização: Julho de 2025