React useDebugValue Secret Hook

Pro Members Only

This lesson is available if you have an active subscription.

Alternatively, some member might be able to gift it to you.

If you already have a subscription, you can sign in.

React useDebugValue Secret Hook

Subscription Required

You must have an active subscription to access this content.
If you already have a subscription, you can sign in.

Use Case for React useDebugValue Hook

Although useDebugValue is not a hook that you will use directly in your React components, but nonetheless it is a hook that can help the developer experience for your custom hooks.

Example Project

Here is a simple example that we use to demonstrate the various features of the React useDebugValue hook.

Person.tsx
App.tsx
import { useState } from 'react';

export type PersonProps = {
firstName: string, setFirstName: (value: string) => void,
lastName: string, setLastName: (value: string) => void,
}

export const Person = ({ firstName, setFirstName, lastName, setLastName }: PersonProps) => {
return (
<>
<label htmlFor='firstName'>First Name</label>
<input id='firstName' value={firstName} onChange={e => setFirstName(e.target.value)} />
<label htmlFor='lastName'>Last Name</label>
<input id='lastName' value={lastName} onChange={e => setLastName(e.target.value)} />
</>
);
}

export const usePersonProps = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');

return { firstName, setFirstName, lastName, setLastName };
}

useDebugValue Reference

Here are some reference ways to utilize the React useDebugValue hook:

// call it multiple times (not recommended as its hard to track)
useDebugValue(firstName);
useDebugValue(lastName);

// use an array (prefer this over multiple calls)
useDebugValue([firstName, lastName]);

// use an object
useDebugValue({ firstName, lastName });

// custom formatted string
useDebugValue(`first: ${firstName}, last: ${lastName}`);

// defer the custom formatting
useDebugValue({ first: firstName, last: lastName }, (value) => {
console.log('format called');
return `${value.first}, ${value.last}`;
});

// defer all execution
useDebugValue(null, (_) => `${firstName}, ${lastName}`);
javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

Although used debug value is not a hook that you will use directly in your React components, however, it is a hook that can greatly enhance the DX or developer experience of your custom hooks. So let's take a look to demonstrate the need for this hook. Let's just consider a very simple use case application. We have some props that we expect for our custom component. And our custom component is pretty simple. It has two simple input fields, first name and last name, and they are wired to the corresponding values and the set functions which we destructure from the past in person props to make it easier for our consumers.

00:33

To use This component, we provide a custom hook called used person props, which basically abstracts the two used state calls that we need to manage the first and the last names. Now that we have a sample custom hook, let's try to use this within our application component. From the person module, we bring in the person component and the used person props Custom hook that we just created. Our application is going to be pretty simple. It has two key pieces of functionality. One is a simple counter managed by U State with increment and decrement, and then we have the person props

01:06

provided by our custom use person. Props hook. Our UI consists of a simple dev displaying the current count and a dev containing the two buttons wired to the decrement and the increment functions. And of course we have our person component for which we are simply using the person props. Now if you jump to the browser, you can see the application works perfectly fine. We can increment and decrement, we can provide a first name, we can provide a last name. However, if you look at the component panel within react dev tools, you might notice something interesting. Within the hooks section we can see the value

01:39

that used state is managing upfront. However, for used person props, we have to expand the hook section to see what values it is managing. The purpose of the used debug value hook is to provide a nice label within our custom hooks so we don't have to expand it to see the values that are relevant. Let's jump back into code and look at our used person props hook and try to improve the developer experience by using a used debug value, which is provided from the main react module. Just like some of the other hooks like used state, this hook takes a simple value which

02:12

will be used as the label. So right now, let's just use the first name as the only label. Now if we jump into the application and provide a first name note that now we can see the label upfront without having to expand the person props hook. We can actually make multiple calls to use the book value. So for example, provide the first name and then provide an additional label in the form of the last name. And now if you jump into the application and provide the last name, you can see that the label shows up as an array of the two values that we passed in. Now, I do highly recommend

02:44

that you don't pick multiple calls to keep things simple. And if you want to provide an array, just provide an array as the value to a single call for use debug value. And this does render out exactly as we saw before. It renders out the array of the first name and the last Name as the label for the used person props hook. In addition to providing an array for the used above value, you can actually even pass in an object. So hey, we are passing in an object containing the first name and the last name member strings. And now if you jump into the ui, you can see that we have this object being displayed as the label

03:17

for percent props. Now, even though you can provide different kinds of values to use debug value and react will try its best to render it out as a nice label. I do highly recommend that you provide a label which is of type string and do your own formatting to be guaranteed that you get the best experience as you glance quickly at the different hooks within the React developer tools. The used bug value hook also takes an optional second callback parameter called format, which can be used to defer the formatting and you can actually even use this

03:48

to improve the performance of this hook. A key feature of this optional second format parameter is that it is actually invoked only once the React developer tools are active in this syntax. The hook actually takes two arguments. The first one is the value which you want to display, and the second one is a format for this value. And here we are doing a simple formatting of value dot first combined with value dot last. But the thing that I want to demonstrate over here is that this function will not get called during standard rendering of this hook,

04:20

and to prove that I've added this console log statement. So if you jump into the application and mess around with the various states to cause lots of re renders, you will not notice the consult log statement. However, if we go into the components panel, that is when that format function will get called and we see the formatted result in the form of this simple string label. The main use case for this of course, is to save up on performance and not running format all the time and only run it if there is an active developer tool session open.

04:53

Now using this, we can actually do something pretty cool as well. We can actually pass in an initial value of null, and then all of our logic only exists as a result of the format function, which of course only executes if there's an actual debug session happening. And in terms of rendering, it's going to be exactly the same as you would expect. We get that nicely rendered first name, common last name, which is of course the result of our format function. As a final thought, I don't recommend adding debug values to every single custom hook that you might have. It is most valuable for custom hooks that are part

05:26

of standard shared libraries that you're using again and again, or that have complex internal data structures that are difficult to inspect without adding a custom label. As always, thank you for joining me and I will see you in the next one.