I'm trying to use useDeferredValue
hook in React 18 to defer updating a part of the UI based on a state variable.
According to React documentation:
During the initial render, the returned deferred value will be the same as the value you 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 background with the new value (so it will return the updated value).
However, when I use useDeferredValue
in my code, I notice that the deferred value changes immediately when the original value changes, instead of after React finishes the original re-render and starts working on a background re-render with the new value. This is not how useDeferredValue
is supposed to work.
const [query, setQuery] = useState("");
const deferredQuery = useDeferredValue(query);
return (
<div>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
<p>Query: {query}</p>
<p>Deferred Query: {deferredQuery}</p>
</div>
);
You can see a live demo of my code here.
I'm using React version 18.2.0 and Chrome version 115. I've also tested my code on other browsers and devices, and the problem persists.
Can anyone explain why useDeferredValue
does not work as expected in my code? How can I fix this issue? Thank you!
UPDATED QUESTION
I added this part to my question to show another use case of useDeferredValue where I need to fetch some data based on the deferred query and update the state accordingly. The fetchSomething
function is a mock API call that returns an array of objects with some random data. The stuff state is an array that stores the fetched data.
const [query, setQuery] = useState("");
const [stuff, setStuff] = useState([]);
const deferredQuery = useDeferredValue(query);
const fetchSth = async (query) => {
const res = await fetchSomething(query);
setStuff(res);
};
useEffect(() => {
fetchSth(deferredQuery);
}, [deferredQuery]);
In this case, I'm also getting immediately changes in the deferred query and the stuff state. For example, when I type "a" in the input, the deferred query and the stuff state change to "a" and the corresponding data right away, instead of waiting for React to finish rendering the main component and start working on the background re-render with the new value.
I expect to see the deferred query and the stuff state change only after React finishes rendering the main component and starts working on the background re-render with the new value. For example, when I type "a" in the input, I expect the deferred query and the stuff state to remain unchanged until React has rendered the main component with "a" as the query, and then change to "a" and the corresponding data in background.
You can see a live demo of my code here.