1

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.

Pluto
  • 4,177
  • 1
  • 3
  • 25
  • 2
    [`useDeferredValue`](https://react.dev/reference/react/useDeferredValue) is for async operations. From your example and description (which include no async ops), it seems like you're searching for a way to store a value from the previous render, such as a [`usePrevious`](https://stackoverflow.com/a/53446665/438273) hook. Is that the case? – jsejcksn Jul 24 '23 at 02:42
  • Logging out variables reveals that it works fine. Update is just too fast to see it in the DOM – Konrad Jul 24 '23 at 02:43
  • @jsejcksn, please help me. this is my codesandbox link: https://codesandbox.io/s/upbeat-curie-rtwy99?file=/src/App.js. how can I use `useDeferredValue` in this case? – Pluto Jul 24 '23 at 03:18
  • @Konrad, What does "Logging out variables" mean? please add the comment or answer. Thank you. – Pluto Jul 24 '23 at 03:23
  • https://codesandbox.io/s/sad-dan-4wl5th?file=/App.js – Konrad Jul 24 '23 at 03:46
  • @Konrad, what is the difference between yours and mine? I think these are the same. Could you please explain in more detail? – Pluto Jul 24 '23 at 03:54
  • @VictorL. Links can be useful for context, but aren't substitutes for including a [mre] in the question. Any code related to the question needs to be included in the question itself. See [ask]. – jsejcksn Jul 24 '23 at 06:33
  • @jsejcksn, thank you for your feedback. I updated my answer to show another use case of `useDeferredValue` where I need to fetch some data based on the deferred query and update the state accordingly. However, I still can't understand why `useDeferredValue` is not working as expected in both cases. Could you please explain how `useDeferredValue` works with concurrent features, such as `Suspense`, and how to use it correctly in my code? I appreciate your help and time. If you need more information or clarification from me, please let me know. – Pluto Jul 24 '23 at 06:55
  • 1
    [^](https://stackoverflow.com/questions/76751014/why-does-usedeferredvalue-not-work-as-expected-in-react-18?noredirect=1#comment135311956_76751014) @VictorL. I'm starting to think this is an [XY problem](https://en.wikipedia.org/wiki/XY_problem). Are you asking for someone to write an explanation for the hook? Or do you assume it's what you need to solve another issue you are facing? What's the actual issue? – jsejcksn Jul 24 '23 at 07:50
  • 1
    @VictorL. I added `console.log` and in the console you can see that values are indeed different – Konrad Jul 24 '23 at 10:08

0 Answers0