| name | react-debugging-advanced |
| description | Advanced React debugging techniques using browser DevTools, React DevTools, performance profiling, and error boundaries. Use for troubleshooting complex React applications and performance issues. |
| allowed-tools | fs_read fs_write execute_bash |
| metadata | {"tags":"debugging,react,webapp","groups":"react","invocation":"model","author":"kiro-cli","version":"1.0","category":"frontend","compatibility":"Requires React DevTools browser extension, modern browser"} |
React Advanced Debugging
Instructions
1. Set up debugging environment
Install React DevTools:
npm install -g react-devtools
Configure development build:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
define: {
__DEV__: true,
},
build: {
sourcemap: true,
},
})
2. Error boundaries and error handling
Comprehensive error boundary:
import React, { Component, ErrorInfo, ReactNode } from 'react';
interface Props {
children: ReactNode;
fallback?: ReactNode;
onError?: (error: Error, errorInfo: ErrorInfo) => void;
}
interface State {
hasError: boolean;
error?: Error;
errorInfo?: ErrorInfo;
}
export class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
() {
.(, error, errorInfo);
.(error, errorInfo);
..?.(error, errorInfo);
.({ errorInfo });
}
() {
.(, {
: error.,
: error.,
: errorInfo.,
: ().(),
: navigator.,
: ..,
});
}
() {
(..) {
(..) {
..;
}
(
);
}
..;
}
}
3. Performance debugging with React DevTools profiler
Performance monitoring component:
import { Profiler, ProfilerOnRenderCallback } from 'react';
const onRenderCallback: ProfilerOnRenderCallback = (
id,
phase,
actualDuration,
baseDuration,
startTime,
commitTime,
interactions
) => {
console.log('Profiler:', {
id,
phase,
actualDuration,
baseDuration,
startTime,
commitTime,
interactions: Array.from(interactions),
});
if (actualDuration > 16) {
console.warn(`Slow render detected in ${id}: ${actualDuration}ms`);
}
};
export const PerformanceProfiler: React.FC<{ children: React.ReactNode; id: string }> = ({
children,
id
}) => {
return (
<Profiler id={id} onRender={onRenderCallback}>
{children}
</Profiler>
);
};
function App() {
(
);
}
4. Custom debugging hooks
Debug hook for component lifecycle:
import { useEffect, useRef } from 'react';
export function useDebugValue(value: any, label: string = 'Debug') {
const prevValue = useRef(value);
useEffect(() => {
if (prevValue.current !== value) {
console.log(`[${label}] Changed:`, {
from: prevValue.current,
to: value,
timestamp: new Date().toISOString(),
});
prevValue.current = value;
}
});
React.useDebugValue(value, (val) => `${label}: ${JSON.stringify(val)}`);
}
export function useRenderCount(componentName: string) {
const renderCount = useRef(0);
useEffect(() => {
renderCount.current += 1;
.();
});
.(renderCount., );
renderCount.;
}
() {
previousProps = useRef<<, >>();
( {
(previousProps.) {
allKeys = .({ ...previousProps., ...props });
: <, { : ; : }> = {};
allKeys.( {
(previousProps.![key] !== props[key]) {
changedProps[key] = {
: previousProps.![key],
: props[key],
};
}
});
(.(changedProps).) {
.(, changedProps);
}
}
previousProps. = props;
});
}
() {
();
(userId, );
(, { userId, data, onUpdate });
}
5. State debugging with Redux DevTools
Enhanced store configuration:
import { configureStore } from '@reduxjs/toolkit';
import { createLogger } from 'redux-logger';
const logger = createLogger({
predicate: () => process.env.NODE_ENV === 'development',
collapsed: true,
duration: true,
timestamp: true,
logErrors: true,
diff: true,
});
export const store = configureStore({
reducer: {
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: ['persist/PERSIST'],
},
}).concat(logger),
devTools: process.env.NODE_ENV === 'development' && {
trace: true,
traceLimit: 25,
actionSanitizer: (action) => ({
...action,
payload: action..() ? : action.,
}),
: ({
...state,
: state. ? { ...state., : } : state.,
}),
},
});
6. Network debugging and API monitoring
API debugging wrapper:
import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
const apiClient = axios.create({
baseURL: process.env.REACT_APP_API_URL,
});
apiClient.interceptors.request.use(
(config: AxiosRequestConfig) => {
const requestId = Math.random().toString(36).substr(2, 9);
config.metadata = { requestId, startTime: Date.now() };
console.log(`[API Request ${requestId}]`, {
method: config.method?.toUpperCase(),
url: config.url,
params: config.params,
data: config.data,
headers: config.headers,
});
return config;
},
(error: AxiosError) => {
.(, error);
.(error);
}
);
apiClient...(
{
{ requestId, startTime } = response.. || {};
duration = .() - (startTime || );
.(, {
: response.,
: response.,
: response.,
: response.,
});
(duration > ) {
.();
}
response;
},
{
{ requestId, startTime } = error.?. || {};
duration = .() - (startTime || );
.(, {
: error.,
: error.?.,
: error.?.,
: error.?.,
: {
: error.?.,
: error.?.,
: error.?.,
},
});
.(error);
}
);
7. Memory leak detection
Memory monitoring hook:
import { useEffect, useRef } from 'react';
export function useMemoryMonitor(componentName: string, interval: number = 5000) {
const intervalRef = useRef<NodeJS.Timeout>();
useEffect(() => {
if (process.env.NODE_ENV === 'development' && 'memory' in performance) {
intervalRef.current = setInterval(() => {
const memory = (performance as any).memory;
console.log(`[Memory ${componentName}]`, {
used: `${Math.round(memory.usedJSHeapSize / 1048576)} MB`,
total: `${Math.round(memory.totalJSHeapSize / 1048576)} MB`,
limit: `${Math.round(memory.jsHeapSizeLimit / 1048576)} MB`,
timestamp: new Date().(),
});
}, interval);
}
{
(intervalRef.) {
(intervalRef.);
}
};
}, [componentName, interval]);
}
() {
mountTime = (.());
cleanupFunctions = useRef<( )[]>([]);
= () => {
cleanupFunctions..(fn);
};
( {
{
lifetime = .() - mountTime.;
.();
cleanupFunctions..( {
{
();
} (error) {
.(, error);
}
});
};
}, [componentName]);
{ addCleanup };
}
Examples
Complete debugging setup
import React from 'react';
import { ErrorBoundary } from './components/ErrorBoundary';
import { PerformanceProfiler } from './components/PerformanceProfiler';
function App() {
return (
<ErrorBoundary
onError={(error, errorInfo) => {
// Send to error tracking service
console.error('App Error:', error, errorInfo);
}}
>
<PerformanceProfiler id="App">
<div className="app">
<Header />
<MainContent />
<Footer />
</div>
</PerformanceProfiler>
</ErrorBoundary>
);
}
export default App;
Debug component with all hooks
function DebugComponent({ userId, data }: Props) {
useRenderCount('DebugComponent');
useMemoryMonitor('DebugComponent');
useDebugValue(userId, 'User ID');
useWhyDidYouUpdate('DebugComponent', { userId, data });
const { addCleanup } = useLeakDetection('DebugComponent');
useEffect(() => {
const timer = setInterval(() => {
console.log('Timer tick');
}, 1000);
addCleanup(() => clearInterval(timer));
}, [addCleanup]);
return <div>Debug Component Content</div>;
}
Troubleshooting
- React DevTools not showing: Ensure development build and extension installed
- Performance profiler not recording: Check if Profiler component wraps target components
- Error boundary not catching errors: Async errors need separate handling
- Memory leaks detected: Check for uncleared intervals, event listeners, subscriptions
- API calls not logged: Verify interceptors are properly configured
- State changes not visible: Ensure Redux DevTools extension is installed and enabled