Debugging React Apps

While developing my calculator app, there were several instances where I needed to step through my code to troubleshoot some issue. However, I didn’t know how. I resorted to console.log() after console.log(). It was tedious, it was tiring; but it caused me to research how React.js apps (and websites in general) are debugged. I have used the browser developer tools to do most things, but I have never used it to step through JavaScript code.

I thought this would be a good opportunity to document how the browser developer tools, React Developer Tools, and Visual Studio Code can be used to debug web applications.

Browser Developer Tools

Any web developer should be familiar with the developer tools (DevTools) in the browser, since they are an invaluable resource when developing a web application. DevTools can be accessed in both Chrome and Firefox by pressing Ctrl + Shift + I or F12. The tools allow you to step through JavaScript code, inspect elements, view the console, get performance insight and more.

Why DevTools Are Useful

  • Debug JavaScript: You can step through JavaScript code by setting breakpoints and use the watch window to see multiple variables within the app. I have experience doing this in C# with Visual Studio, but did not know it was possible with JavaScript.
  • Inspector Tool: Inspect Element is a feature in all major browsers. It allows you to inspect HTML/CSS as well as modify HTML/CSS. You can also inspect and modify flexbox elements. In addition to this you can use it to test scripts, debug errors, and see a web page’s metadata. When I was working in QA, I had to use Copy CSS Path so that I could program Selenium to find HTML elements without an id attribute.
  • Console: Information logged from your web application can be viewed from the console. Also, warnings and error messages will appear here.
  • Network: The network tab lets you view the HTTP requests that make up each page load within a user’s session. It also allows you to inspect the corresponding HTTP response.  In my last developer role, I used this frequently to inspect how long some of our internal APIs were taking to process and to look at other details.

React Developer Tools

While writing this section, I came across this article on React DevTools by freeCodeCamp. It is more in depth than what I’ll cover here, but this section is still useful if you want a brief high level overview. Good thing this post wasn’t just on React DevTools or it would’ve made it obsolete!

From React’s documentation:

Use React Developer Tools to inspect React components, edit props and state, and identify performance problems.

So the React Developer Tools offer similar functionality to DevTools, except they are targeted towards React components instead of HTML elements.

React Developer Tools can be downloaded as a browser extension for most of the popular browsers. The tools can be broken into two parts, components and profiler. Once the tools have been installed, you will see “Components” and “Profiler” tabs in DevTools whenever visiting a page using React:

React DevTools 1

Demo Code

I created a small project for demoing the React DevTools. You can clone it here.

This is just enough for us to demo the Components and Profiler tabs. We have an input field that is tied to our useState Hook and a List component that we pass props to.

Components Tab

If you run the app and navigate to the Components tab in DevTools, the first thing you’ll notice is that it allows us to see the component tree:

Components Tab 1

We can click on any node and see the props, state, and hooks of that component:

Components Tab 2

If we type in our input field, we will see the state change accordingly:

Components Tab 3

We can also change our state by changing it directly in the DevTool and pressing Enter:

Components Tab 4

Similarly, we can manipulate the props of our ListItem component:

Components Tab 5

Profiler Tab

The profiler allows us to identify performance problems in our application. Navigate to the Profiler tab in DevTools, go to settings and check the box for “Highlight updates when components render.”:

Profiler Tab 1

Now when we type into our input field, we can see when each of our components has to render:

Profiler Tab 2

Let’s use the profiler to get some more information about what’s being rendered. Click the “Start profiling” button all the way to the left:

Profiler Tab 3

Next, type a single character into the input field and then press the button again to stop profiling:

Profiler Tab 4

The group of bars in the profiler is what’s called a flame chart. It shows what had to render in a recording and how long that rendering took. Components in yellow took the longest, components in blue rendered the fastest, and components in gray did not render at all.

So, we can see that our list had to rerender when we typed in our input field. This is a flaw in our application, our List should not be updating when our input is changed. For something like this, the impact is negligible. But if we had a larger application with many components nested within our App component, it could cause performance issues when everything has to rerender because some unrelated component changed.

There are a few ways we could resolve this, I am going to show one way here. Let’s create a new component above our App called Input and move our useState hook and input JSX there:

Now, when we type in our input field again, only our Input component will rerender. If we do another recording in the profiler, we can confirm this because our Input component is yellow and our App and List are gray:

Profiler Tab 5

Visual Studio Code

Lastly, we can step through our code with Visual Studio Code. Open VS Code and go to Run and Debug and select the Web App (Chrome) debugger:

VS Code 1

We’ll then be prompted with a launch.json file:

Make sure request is set to “launch” just like in the snippet. Also, change your url to be whatever you are running React on. For me, it is “http://localhost:3000“. So, the resulting JSON should look like:

Now, in VS Code, set a breakpoint at the beginning of where we define our App component by either clicking to the left of the line number or putting your cursor on that line and pressing ShiftF9:

VS Code 2

Press F5 to start debugging the app. Our breakpoint should now get hit:

VS Code 3

We can now set other breakpoints, and pause during the execution of our app to see what the status is of variables or the call stack. You can add variables to the “Watch” window to keep tabs on what value they’re set to at different points in time.

Conclusion

That wraps up debugging web applications. These tools give you a lot of power to tweak and improve your React project efficiently and quickly. Besides the React DevTools section, everything I said here can be applied to web applications no matter the technology.

If you have any questions about something I said here, feel free to reach me by email on the Contact page. Also, if you want to be updated when I publish future posts, make sure to subscribe!