Debugging a React app using methods such as breakpoints, step-through, and logging to the console is perfectly possible, but it can sometimes be a difficult process—especially when debugging an application you have not seen before. Fortunately, by installing the React developer tools, some of these difficulties can be overcome. This guide will show you how to use the React developer tools Components tab to help navigate and debug an unfamiliar codebase.
The guide will be based on a React web application; however, the developer tools can also be used with a React Native application. The application used in the examples is here.
The first thing to do is to install the developer tools. How you do this depends on the browser you are using to run the application. For Chrome and Firefox the developer tools are available as browser extensions and can be found in the appropriate extension store. If using a different browser, the developer tools can be installed as a standalone app from this npm package.
Once installed, either in the standalone application or the browser developer tools, two new tabs will be available: Components and Profiler. This guide will use the Components tab.
One of the biggest problems when looking at a React application that you have never seen before is where to find the code for what you see in the browser. React applications will often use techniques such as component composition and, as such, will contain many small components, so identifying which component renders what in the browser can be tricky. This is one time the developer tools Components tab can be very useful.
When you open the components tab, in the left-hand panel you will see the React component tree:
Hover over a component and the HTML it has rendered will highlight in the browser.
Also, by clicking this button
you will be able to hover over any of the HTML elements in the browser to highlight the React component responsible for rendering it or click on an HTML element to select the relevant React component in the tree.
Once you've identified the React component you want to look at in detail, you can select it in the tree, and in the right hand panel you can find the file and line of code that rendered it. So in the example application, if you select the first Container
component in the tree, you will see this:
If you go to line 24 of Selectors.jsx
it looks like this:
1<Container>
2 ...
3</Container>
You can also view the component code by clicking the view source button
, which will open the code for the component in the browser developer tools source tab.
Sometimes you may see components in the tree named Anonymous
. This is usually caused by developers exporting the component as an unnamed default using syntax such as:
1export default () => {...};
2export default function() {...}
3export default class extends Component {...}
All of the above techniques will still work to find the code for the component, it just has no name. In order to ensure your components are named in the tree, replace the above syntax with:
1const AComponent = () => {...}
2export default AComponent;
3
4export default function AComponent() {...}
5export default class AComponent extends Component {...}
If you see a component in the tree annotated like this
,
it has been rendered by a higher order component. In order to have any higher order component you build to look like this in the tree, you will need to give it a display name of
with(<name>)
, otherwise it will still appear in the tree just as a regular component. The withChangedCount
higher order component in the example application defines its display name like this:
1const WithChangedCount = props => {...};
2WithChangedCount.displayName = `withChangedCount(${Component.name})`;
3return WithChangedCount;
Often you will only want to see certain components or, more likely, not see some. You can do this by accessing the component filter from the React Developer Tools settings
. This gives you the option to hide components matching a specified criteria. You can hide components that have a name or file location matching a regular expression, hide all higher order components, which will be identified as described above, or hide all components of a particular type:
By default, host components (those based on standard HTML elements) will be hidden, allowing you to concentrate more on the components that are part of the application. If you want to see those components, you can turn off the filter or, if what you really need is to look at the actual markup rendered by the component, click the inspect button
, which will take you to the DOM element in the browser developer tools.
You can also search for components by name by typing a regular expression into the search box like this:
When a component has been selected in the tree, its current state and props are shown in the right hand panel. As a developer, this allows you to check at any point when debugging an application that the state and props of components are as you expect them to be.
Along with inspecting state and props, it is also possible to change them, which is very useful as a simple way to check how some UI looks under different circumstances and to debug how components interact depending on their current state/props. For instance, in the example app, you could select one of the NumberSelector
components in the tree and in its props add an isSelected
prop, like this:
Adding this prop would then check the checkbox of that component. Note that it would only check the box, not call the onSelectChanged
callback as you are changing the prop, not checking the box through the UI.
You could also change the state hook in the AppContextProvider
component, which controls the running total:
This will update the total displayed in the browser and any subsequent changes to that total will be based on this new state.
With the React developer tools, it is also possible to view which components were responsible for rendering the selected component. Often this can be seen by looking at the component tree, but this is not always the case.
To view which components rendered one of the NumberSelector
components in the example app, you can select the component in the tree, and in the right-hand panel you will see:
This shows that the NumberSelector
was rendered by the Selectors
component, which was rendered by the App
component. If you look at the component tree, you can see that the NumberSelector
is a child of the Container
component ,but the Container
was not responsible for rendering it. This is because the application has been built using component composition and the list of NumberSelector
components were passed as children to the Container
from within the Selectors
component, like this:
1return (
2 <Container>
3 {Object.entries(numberSelectors).map(([text, { value }]) => (
4 <NumberSelector
5 key={text}
6 text={text}
7 onSelectChanged={handleSelectChanged(text, value)}
8 />
9 ))}
10 </Container> );
You can also view this information by double-clicking on a component in the tree, which will change the tree to only show components rendered by the selected component. The components that rendered it will be shown in the bar at the top:
When using the React Suspense API to handle the UI, it can sometimes be difficult to view how the UI will look while waiting for asynchronous operations. Sometimes the only way to do this is to add some code to make the async operation take a very long time just to be able to check that the UI looks as expected. With the React developer tools this is very simple. You can select a component from the tree and click the suspend button
, which will suspend the component, thereby rendering the UI as the Suspense API would. The example application is wrapped in this
Suspense
component:
1<Suspense fallback={<div>This is a suspense fallback</div>}>
2 ...
3</Suspense>
When the suspend button is clicked, the content specified in the fallback
prop will be displayed.
This guide has shown how the React developer tools can be used to make navigating around a React application and debugging the components that are part of it much easier and faster. The code for the example application can be found here.