Debugging Tips

Master the essential tools and techniques for finding and fixing bugs in your code quickly and efficiently.

What You'll Learn

  • Using console.log effectively
  • Browser DevTools essentials
  • Reading stack traces
  • Debugging React components
  • Step-by-step debugging process
  • Common debugging strategies

The Debugging Mindset

What is Debugging?

Debugging is the process of finding and fixing errors (bugs) in your code. It's a normal part of development—even experienced developers spend significant time debugging!

The Golden Rule

Change one thing at a time, then test.

If you change multiple things, you won't know which change fixed (or broke) something.

Console.log Debugging

Basic Usage

The simplest and most common debugging tool:

console.log('Value:', someVariable);

Strategic Placement

Check if code runs:

function handleClick() {
  console.log('Button clicked!'); // Does this run?

  // ... rest of function
}

Check variable values:

const [count, setCount] = useState(0);

function increment() {
  console.log('Before:', count); // What's the current value?
  setCount(count + 1);
  console.log('After:', count); // Did it change?
}

Check function inputs:

function greet(name: string) {
  console.log('Received name:', name); // What was passed in?
  return `Hello, ${name}`;
}

Check data flow:

useEffect(() => {
  console.log('Effect running');
  console.log('User data:', user);
}, [user]);

Advanced Console Methods

Table view for arrays/objects:

const users = [
  { id: 1, name: 'Alice', age: 25 },
  { id: 2, name: 'Bob', age: 30 },
];

console.table(users); // Displays as formatted table

Grouping logs:

console.group('User Login Process');
console.log('Step 1: Validate input');
console.log('Step 2: Check credentials');
console.log('Step 3: Create session');
console.groupEnd();

Warnings and errors:

console.warn('This feature is deprecated'); // Yellow warning
console.error('Failed to save data'); // Red error

Object inspection:

const user = { name: 'Alice', settings: { theme: 'dark' } };

console.log('User:', user); // Click to expand in console
console.dir(user); // Shows object structure

Console.log Best Practices

1. Use descriptive labels:

// ❌ Bad
console.log(data);

// ✅ Good
console.log('API Response:', data);

2. Log multiple values:

console.log('Count:', count, 'Total:', total, 'Average:', average);

3. Use objects for clarity:

// ✅ Great for multiple values
console.log({ count, total, average });

4. Remove before committing:

# Search for console.logs before committing
git diff | grep console.log

Browser DevTools

Opening DevTools

  • Mac: Cmd + Option + I
  • Windows: F12 or Ctrl + Shift + I

Console Tab

View all logs:

  • All console.log output appears here
  • Click to expand objects
  • Filter by type (errors, warnings, logs)

Try code live:

// Type directly in console:
document.querySelector('h1').textContent = 'New Title';

Elements Tab

Inspect HTML:

  1. Click element inspector icon (top-left)
  2. Hover over page elements
  3. Click to select
  4. View HTML structure

Live CSS editing:

  1. Select element
  2. Edit styles in right panel
  3. Changes apply instantly
  4. Copy working CSS

Check computed styles:

  • See final CSS values after all rules applied
  • Useful for debugging specificity issues

Network Tab

Monitor API requests:

  1. Open Network tab
  2. Reload page or trigger action
  3. See all requests/responses

Check request details:

Headers: Request method, status code
Preview: Formatted response data
Response: Raw response
Timing: How long request took

Debug failed requests:

  • Red = failed (4xx, 5xx errors)
  • Click to see error details
  • Check Headers tab for status code

Sources Tab

Set breakpoints:

  1. Find file in left panel
  2. Click line number to add breakpoint
  3. Code pauses when line runs
  4. Inspect variables at that moment

Step through code:

  • Step over: Next line
  • Step into: Enter function
  • Step out: Exit function
  • Resume: Continue execution

React DevTools

Install extension:

Components tab:

  • View component tree
  • See props and state
  • Edit values live
  • See re-renders

Profiler tab:

  • Measure component performance
  • Find slow renders
  • Optimize re-renders

Reading Stack Traces

What is a Stack Trace?

Shows the path code took before error:

Error: Cannot read property 'name' of undefined
    at UserProfile (UserProfile.tsx:15)
    at div
    at App (App.tsx:25)

How to Read It

Bottom-to-top flow:

  1. App.tsx:25 - App component called
  2. UserProfile.tsx:15 - UserProfile component called
  3. Error happened here - Line 15 of UserProfile.tsx

Find the problem:

  1. Start at the top (where error occurred)
  2. Look at file name and line number
  3. Open file and go to that line
  4. Check what could be undefined

Example

TypeError: Cannot read property 'email' of undefined
    at ContactForm (ContactForm.tsx:42)

What to check:

// Line 42 in ContactForm.tsx
<input value={user.email} /> // user is undefined!

// Fix: Check if user exists
<input value={user?.email || ''} />

Debugging React Components

Component Not Rendering

Check 1: Is it imported?

// ❌ Missing import
export default function Page() {
  return <Header />; // Error: Header is not defined
}

// ✅ With import
import Header from '@/components/layout/Header';

Check 2: Is it exported?

// ❌ Not exported
function Button() {
  return <button>Click</button>;
}

// ✅ Exported
export default function Button() {
  return <button>Click</button>;
}

Check 3: Is path correct?

// Check exact file location
import Button from '@/components/ui/Button'; // Must match actual path

Props Not Working

Check parent is passing them:

// Parent
<Card title="Test" /> // ✅ Passing title

// Child
interface CardProps {
  title: string;
}

export default function Card({ title }: CardProps) {
  console.log('Received title:', title); // Check value
  return <h3>{title}</h3>;
}

Check prop names match:

// ❌ Mismatch
<Card title="Test" />

function Card({ name }: { name: string }) { // Looking for 'name' not 'title'

// ✅ Match
<Card title="Test" />

function Card({ title }: { title: string }) {

State Not Updating

Check setter is called:

const [count, setCount] = useState(0);

function increment() {
  console.log('Before:', count);
  setCount(count + 1); // Is this line running?
  console.log('After:', count); // Won't show new value yet!
}

State updates are async:

// ❌ Won't work as expected
setCount(count + 1);
console.log(count); // Still shows old value!

// ✅ Use effect to see updates
useEffect(() => {
  console.log('Count changed to:', count);
}, [count]);

Check dependencies:

useEffect(() => {
  console.log('User:', user);
}, [user]); // Only runs when 'user' changes

Step-by-Step Debugging Process

When Something Breaks

1. Read the error message:

Don't panic! Read the full error.
Note: file name, line number, error type

2. Find the line:

// Open the file
// Go to the line number
// Look at what's on that line

3. Add console.logs:

// Above the error line
console.log('Before error, variable is:', someVariable);

4. Check values:

Are variables what you expect?
Is something undefined/null?
Is data the right type?

5. Google the error:

Copy error message
Search: "react [error message]"
Check Stack Overflow, GitHub issues

6. Try a fix:

Make ONE change
Test
If it works, understand why
If not, undo and try something else

Common Debugging Strategies

Cut code in half to find problem:

function processData() {
  console.log('Step 1'); // Works
  const data = fetchData();
  console.log('Step 2'); // Works
  const cleaned = cleanData(data);
  console.log('Step 3'); // Doesn't run - error in cleanData!
  return cleaned;
}

Rubber Duck Debugging

Explain code line-by-line:

Talk through code to yourself (or a rubber duck):

  1. "This function receives user data..."
  2. "Then it checks if email exists..."
  3. "Oh! What if email is undefined?" ← Often find the bug!

Comment Out Code

Isolate the problem:

function handleSubmit() {
  validateInput(); // Works
  // sendToAPI(); // Commenting this out - does error go away?
  // updateUI(); // If yes, problem is in one of these
}

Check Assumptions

Question everything:

// Assumption: user is always defined
<p>{user.name}</p>

// Reality: user might be null on first render
// Fix:
<p>{user?.name || 'Loading...'}</p>

Simplify

Reduce to minimal example:

// Complex (hard to debug):
<Card user={users.find(u => u.id === selectedId)} />

// Simplified (easier):
const selectedUser = users.find(u => u.id === selectedId);
console.log('Selected user:', selectedUser);
<Card user={selectedUser} />

Debugging Checklist

When stuck, go through this list:

  • Did I save the file?
  • Did I refresh the browser?
  • Are there errors in the console?
  • Did I check the Network tab (for API issues)?
  • Did I add console.logs?
  • Did I read the full error message?
  • Did I check the file and line number?
  • Is the component imported correctly?
  • Are props being passed correctly?
  • Did I check for typos?
  • Did I Google the error?
  • Did I try hard refresh (Cmd/Ctrl + Shift + R)?
  • Did I restart the dev server?

Pro Tips

1. Keep DevTools Open

Always have console open while developing—catch errors immediately.

2. Test Incrementally

Don't write 50 lines then test. Write 5, test, repeat.

3. Use Git to Undo

# See what you changed
git diff

# Undo all changes
git checkout .

# Undo specific file
git checkout -- path/to/file.tsx

4. Create Minimal Reproductions

If stuck, create smallest possible example that shows the bug.

5. Take Breaks

Seriously! Often the solution appears after stepping away.

Quick Reference

Console methods:

console.log()    // General logging
console.error()  // Errors (red)
console.warn()   // Warnings (yellow)
console.table()  // Arrays as table
console.dir()    // Object structure

DevTools shortcuts:

Cmd/Ctrl + Option/Shift + I  - Open DevTools
Cmd/Ctrl + Shift + C         - Inspect element
Cmd/Ctrl + Shift + R         - Hard refresh

React DevTools:

Components tab - View props/state
Profiler tab   - Performance

Debugging process:

1. Read error
2. Find line
3. Add console.logs
4. Check values
5. Google error
6. Try fix

What's Next

Now you know how to debug issues. Learn when to ask for help:

Getting Help →