useDeferredValue — React Hook

AkashSDas
2 min readMar 29, 2024

--

useDeferredValue allow us to defer updating parts of UI.

Following is the signature of useDeferredValue:

const deferredValue = useDeferredValue(value);

The argument value is the value we want to defer. It can have any type. During the initial render, the returned deferred value will be the same as the value we provided. During updates, React will first attempt a re-render with the old value (so it will return the old value), and then try another re-render in the background with the new value (so it will return the updated value).

The deferred “background” rendering is interruptible. For example, if we type into the input again, React will abandon it (only displaying will be deferred) and restart with the new value. React will always use the latest provided value.

Here is an example that showcases useDeferredValue usage:

import { useState, useDeferredValue, ChangeEvent, useMemo } from "react";

export default function App(): JSX.Element {
const [input, setInput] = useState("");
const deferredValue = useDeferredValue(input);

const lists = useMemo(
function () {
const dataList: string[] = [];
for (let i = 0; i < 10_000; i++) {
dataList.push(deferredValue);
}
return dataList;
},
[deferredValue]
);

function handleChange(e: ChangeEvent<HTMLInputElement>) {
setInput(e.target.value);
}

return (
<section>
<input type="text" value={input} onChange={handleChange} />

{lists.map((list) => {
return <li>{list}</li>;
})}
</section>
);
}

Deferring re-rendering for a part of the UI

We can also apply useDeferredValue as a performance optimization. It is useful when a we of your UI is slow to re-render, there’s no easy way to optimize it, and you want to prevent it from blocking the rest of the UI.

In this example, we render a list of text whenever the text changes. This change is slow and requires optimization. Since we can’t really memoize the component with React.memo since the text itself changes everyt time. Therefore we’ve to defer the change of text.

import { useState, useDeferredValue, ChangeEvent } from "react";

export default function App(): JSX.Element {
const [input, setInput] = useState("");
const deferredValue = useDeferredValue(input);

function handleChange(e: ChangeEvent<HTMLInputElement>) {
setInput(e.target.value);
}

return (
<section>
<input type="text" value={input} onChange={handleChange} />
<List text={deferredValue} />
</section>
);
}

function List({ text }: { text: string }) {
return (
<div>
{Array.from({ length: 10_000 }).map((_, index) => (
<div key={index}>{text}</div>
))}
</div>
);
}

--

--