Debugging React Apps: A Professional Guide to Troubleshooting
Master debugging React apps with React DevTools. Learn to inspect state, trace props, and profile performance to fix bugs in your movie browser project.
Previously in this course, we explored introduction to testing to catch regressions automatically. While automated tests are vital, you’ll inevitably face scenarios where the UI isn't behaving as expected during manual exploration. In this lesson, we move from testing to debugging, specifically focusing on how to inspect and diagnose your application's internal state and performance using professional tooling.
The Power of React DevTools
When you are building a complex UI like our movie browser, the standard browser console is rarely enough. While console.log() has its place, it becomes noisy and cluttered when you need to track state across dozens of components.
The React DevTools browser extension is the single most important tool in your kit. Once installed, it adds two new tabs to your browser’s inspection pane: Components and Profiler.
Inspecting State and Props
The "Components" tab displays the current hierarchy of your React app. It mirrors your JSX structure, allowing you to click on any component to see:
- Props: What data was passed in from the parent.
- State: The current values held by
useStatehooks. - Hooks: A list of active hooks (like
useEffectoruseContext) and their current values.
Pro-tip: You can click the "eye" icon to inspect a component in the console, which makes the component instance available as a global variable $r. You can then inspect its props and state directly in the console using $r.props or $r.state.
Identifying State Issues
State bugs are the most common source of frustration in React development. If your movie browser isn't updating the search results, the issue is almost always a mismatch between what you think the state is and what it actually is.
Let's look at a common scenario in our project where a filter toggle fails to update the list:
JAVASCRIPT// A common mistake in our MovieList component const [filter, setFilter] = useState(false); const handleToggle = () => { // Bug: We are passing a static value instead of a functional update setFilter(!filter); console.log("Filter is now:", filter); // This will log the OLD value! };
If you use React DevTools, you don't need to guess. Select the MovieList component in the DevTools tree. You can manually edit the filter state value right in the sidebar to see if the UI updates correctly. If the UI changes when you flip the switch in DevTools but fails when you click the button, you know your handleToggle logic is the culprit.
Profiling Component Performance
Once your app is functional, you'll want to ensure it’s performant. As we learned in React performance debugging: How to trace component re-renders, unnecessary re-renders are the silent killers of user experience.
The Profiler tab in React DevTools allows you to record a "session" of your app.
- Click the "Record" button (the circular icon).
- Perform the action (e.g., typing in the search bar).
- Stop the recording.
React will generate a flame graph showing exactly which components rendered and why. If a component rendered, the profiler will tell you if it was due to a prop change, a state change, or a parent re-render. This is invaluable when you've finalized the movie browser and notice it feels sluggish.
Hands-on Exercise: Inspecting the Movie Browser
- Open your movie browser project in your browser.
- Open React DevTools and find your
MovieCardcomponents. - Select a card and verify its
props(liketitleandposterUrl). - Trigger a search action. Watch the "Components" tree highlight in green; this indicates the component is re-rendering.
- If you find a component that re-renders but doesn't actually change visually, record a session in the Profiler to identify the trigger.
Common Pitfalls
- Trusting the Console Too Soon: Beginners often log state immediately after calling
setState. Remember that state updates are asynchronous; the log will reflect the previous state, not the updated one. Use the DevTools UI instead. - Ignoring the "Why": When performance profiling, don't just look for what is slow. Look at the "Why did this render?" section in the Profiler. Often, you'll find that a component is re-rendering because it's receiving a new object reference every time the parent renders—a classic bug that can be fixed with
useMemo. - Component Over-nesting: If your folder structure is clean but your component tree in DevTools looks like a "spaghetti" of providers, you might be over-complicating your state architecture.
Recap
Debugging is an iterative process of elimination. Start by verifying your data flow with the Components tab, then use the Profiler to ensure your rendering logic is efficient. By mastering these tools, you move from "guessing" why a bug exists to "observing" the exact state of your application.
Up next: We will move to the final stages of your project by learning about Deployment Basics, where you'll take your local movie browser and put it live on the web.
Work with me

Headless WordPress + Next.js Frontend Development
Keep WordPress for content, get a lightning-fast Next.js frontend. The best of both worlds — familiar editing, modern speed.

React & Next.js Dashboard / Admin UI Development
A clean, data-rich dashboard UI in React or Next.js — charts, tables, and real-time data that your users will actually enjoy using.