4

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.

10
  • 2
    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 hook. Is that the case? Commented Jul 24, 2023 at 2:42
  • Logging out variables reveals that it works fine. Update is just too fast to see it in the DOM Commented Jul 24, 2023 at 2:43
  • @jsejcksn, please help me. this is my codesandbox link: codesandbox.io/s/upbeat-curie-rtwy99?file=/src/App.js. how can I use useDeferredValue in this case? Commented Jul 24, 2023 at 3:18
  • 1
    ^ @VictorL. I'm starting to think this is an 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? Commented Jul 24, 2023 at 7:50
  • 1
    @VictorL. I added console.log and in the console you can see that values are indeed different Commented Jul 24, 2023 at 10:08

1 Answer 1

4

The component (for example List) which is rendered based on deferred value should be wrapped with React.memo. And rendering work inside List component should be heavier than your device can handle.

See the documentation here, useDeferredValue works based on user's device parameters. If device is powerful enough, changes will reflect instantly.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.