Debugging Tools
Master debugging tools and techniques for React Native development including Flipper, React DevTools, and native debugging. This is a foundational concept in cross-platform mobile development that professional developers rely on daily. The explanations below are written to be beginner-friendly while covering the depth and nuance that comes from real-world React Native experience. Take your time with each section and practice the examples
Debugging Tools
Use Flipper, React DevTools, and native debugging tools to identify and fix issues in React Native applications.. This is an essential concept that every React Native developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Debugging Setup
- Install and configure Flipper for React Native — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Set up React DevTools for component inspection — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Configure Chrome DevTools for JavaScript debugging
- Set up native debugging for iOS and Android — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Configure network inspection and API monitoring — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Set up performance profiling tools — a critical concept in cross-platform mobile development that you will use frequently in real projects
Debugging Techniques
Implement effective debugging strategies including logging, breakpoints, and performance profiling.. This is an essential concept that every React Native developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
comprehensive Debugging Example
// utils/debugger.js
import { Platform, Alert } from 'react-native';
import crashlytics from '@react-native-firebase/crashlytics';
import analytics from '@react-native-firebase/analytics';
class Debugger {
constructor() {
this.isDebugMode = __DEV__;
this.logLevel = this.isDebugMode ? 'debug' : 'error';
this.logs = [];
}
// Logging methods
log(level, message, data = null) {
const timestamp = new Date().toISOString();
const logEntry = {
timestamp,
level,
message,
data,
platform: Platform.OS,
version: Platform.Version,
};
// Store logs in memory for debugging
this.logs.push(logEntry);
// Keep only last 100 logs
if (this.logs.length > 100) {
this.logs.shift();
}
// Console logging in debug mode
if (this.isDebugMode) {
console.log(`[${level.toUpperCase()}] ${message}`, data);
}
// Send to crashlytics in production
if (!this.isDebugMode && level === 'error') {
crashlytics().log(`[${level}] ${message}`);
if (data) {
crashlytics().recordError(new Error(JSON.stringify(data)));
}
}
// Send to analytics
analytics().logEvent('debug_log', {
level,
message: message.substring(0, 100), // Limit message length
});
}
debug(message, data = null) {
this.log('debug', message, data);
}
info(message, data = null) {
this.log('info', message, data);
}
warn(message, data = null) {
this.log('warn', message, data);
}
error(message, data = null) {
this.log('error', message, data);
}
// Performance monitoring
startTimer(label) {
const startTime = Date.now();
return {
end: () => {
const duration = Date.now() - startTime;
this.debug(`Timer ${label} completed`, { duration });
return duration;
}
};
}
// Memory monitoring
checkMemoryUsage() {
if (this.isDebugMode) {
const memoryInfo = {
usedJSHeapSize: performance.memory?.usedJSHeapSize || 0,
totalJSHeapSize: performance.memory?.totalJSHeapSize || 0,
jsHeapSizeLimit: performance.memory?.jsHeapSizeLimit || 0,
};
this.debug('Memory usage', memoryInfo);
return memoryInfo;
}
}
// Network monitoring
logNetworkRequest(url, method, status, duration, error = null) {
const networkLog = {
url,
method,
status,
duration,
error,
timestamp: new Date().toISOString(),
};
this.debug('Network request', networkLog);
if (error) {
this.error('Network error', networkLog);
}
}
// Error boundary integration
logError(error, errorInfo) {
this.error('React Error Boundary', {
error: error.toString(),
errorInfo,
stack: error.stack,
});
// Send to crashlytics
if (!this.isDebugMode) {
crashlytics().recordError(error);
}
}
// User action tracking
trackUserAction(action, data = {}) {
this.debug('User action', { action, data });
analytics().logEvent('user_action', {
action,
...data,
});
}
// Get all logs for debugging
getAllLogs() {
return this.logs;
}
// Clear logs
clearLogs() {
this.logs = [];
}
// Export logs for debugging
exportLogs() {
const logsString = JSON.stringify(this.logs, null, 2);
if (this.isDebugMode) {
console.log('=== EXPORTED LOGS ===');
console.log(logsString);
console.log('=== END LOGS ===');
}
return logsString;
}
// Show debug panel in development
showDebugPanel() {
if (!this.isDebugMode) return;
const logs = this.getAllLogs();
const recentErrors = logs.filter(log => log.level === 'error').slice(-5);
Alert.alert(
'Debug Panel',
`Total Logs: ${logs.length}\nRecent Errors: ${recentErrors.length}\nMemory: ${this.checkMemoryUsage()?.usedJSHeapSize || 'N/A'} bytes`,
[
{ text: 'Export Logs', onPress: () => this.exportLogs() },
{ text: 'Clear Logs', onPress: () => this.clearLogs() },
{ text: 'Close', style: 'cancel' },
]
);
}
}
// Create singleton instance
const debugger = new Debugger();
// React Native Debugger integration
if (__DEV__) {
// Add debugger to global scope for easy access
global.debugger = debugger;
// Add shake gesture listener for debug panel
import { DeviceEventEmitter } from 'react-native';
DeviceEventEmitter.addListener('shake', () => {
debugger.showDebugPanel();
});
}
export default debugger;