Intro to debugging ReactJS applications

Step 0 — get to know your browser

Most of the tools you need are already available to you, integrated with the browser — I’m talking about the browser’s developer tools. In most cases you can open them by pressing F12 or right clicking and selecting “Inspect”:

Chrome developer tools with Dark theme, inspecting Discordapp.com page

Code linting

While a linter might not help you debug your application it might prevent you from introducing the error in the first place. If you don’t want to spend time configuring and fine-tuning your ESLint (I recommend ESLint here as it’s one of the most popular and powerful) you can use the react-app preset.

Console — your first and most powerful friend

The console window is one of the most important tools at your disposal. Not only does it show all the messages your application is logging using console.log it also shows the majority of error messages in browser caused by your app. On top of that it’s an REPL environment into which you can type any valid JS code and have it executed right away.

const myObject = { name: 'BTM' }
console.log(myObject);
myObject.name = 'John';
Looks ok, right?
BTM === John (no, not really …)

Network tab

There is a very high chance that your application uses some form of communication with a server, and ther ewill be times that you will get wrong data or data will come in a shape you weren’t expecting it. The Network tab is your “go to” here. It will track all HTTP and Websocket requests that happened since you opened the tool (this is sadly not true for Websockets — it will only show communication happening over sockets that were opened after you opened the Developer Tools, so if you need to spy on WS remember to have the tool opened beforehand):

A detailed view of an response from Discord
  • a general rule-of-thumb is “red requests failed, white requests are OK”
  • each request can have multiple states, keep an eye out on “Pending” requests — if the status persists for a longer time, it might mean you mistyped the URL or the backend is having troubles
  • when you click on the request a detailed tab will open — “Preview” and “Response” tabs will show your data; if it looks like the data is OK but you can’t parse it in your app, check the “Content-type” in “Headers” tabs — sometimes servers will send you JSON data as text or HTML which can break some tools
  • a very common error which results in data being visible in “Network” tab but not accessible to your app is failing the CORS protocol. Keep an eye out for errors like this in your “Console” section:
CORS request failed

React Developer Tools

A deceivingly small browser extension from Facebook will be your go-to tool when checking if the data and JSX structure is OK. You can either download the extension from the library for your browser or grab the standalone version.

Discord Messages component inspected in React Developer Tools
$r = this

Serious debugging — breakpoints

Now that we covered all the “easy” things let’s move into the “real world debugging” — working with breakpoints. A breakpoint is an instruction in code which will stop all the execution and fire up a debugger. There are 2 ways of setting up breakpoints that you will find handy:

  • adding debugger; to your source code — when the parser encounters this directive, and the Developer Tools are open it will trigger a breakpoint
  • finding the point on which we want to break in the Develooper Tools (“Sources” tab) and clicking on the line number — this will add a visual marker and will act exactly the same as above; breakpoints set up this way persist through browser refresh
Breakpoint active
  • the navigation panel on the top — allowing us to resume the application, step backwards / forwards in execution or disable all breakpoints
  • the callstack — shows us what functions were called in order to get to the current application state
  • scope — shows what variables are available at the current execution point in what scope (local, global, closure) along with their values; you can also change the values at this point, which — when resumed — will be reflected in your application
  • the console is now hooked to the application state, you have access to all variables shown in “Scope” — this allows you to change values in code that is in other cases not accessible from window namespace (e.g. you get access to components this).

Specific tools

While the above described tools will come in handy in any JS / ReactJS application, there are some tools that you might find useful when working with specific issues / libraries, some of which are:

why did you update?

A small library that integrates with your components that shows you why a component did re-render; while the main goal is to provide ways to check for potential optimizations, it is generally useful when debugging rendering issues

redux-logger

Another small console addition, this time for when you are working with Redux. Main purpose is logging out state changes and actions handled by Redux.

redux-devtools

A more advanced extension useful when working with Redux. Comes in two flavors — a library to add to your application and a browser extension. Main selling point of Redux Devtools is the ability to export / import state as a JSON file (so your testers can share the state with developer when reporting bugs) and the “time travel” which allows you to rewind and fast-forward through a history of Redux reducer states.

redux-immutable-state-invariant

Immutability is one of the main assumptions of Redux, but sometimes a mutation slips through. Adding this middleware will help you track such errors by providing console messages when such a situation takes place.

rubber-duck debugging

No really, hear me out on this one.

Credit: https://en.wikipedia.org/wiki/Rubber_duck_debugging#/media/File:Rubber_duck_assisting_with_debugging.jpg

Know of any good tools or techniques?

If you know of any good tool or technique that is worth sharing with other React developers, please let me know in the comments bellow :)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store