Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stale values returned from useOptimistic when state changes #57662

Closed
1 task done
dorshinar opened this issue Oct 28, 2023 · 7 comments
Closed
1 task done

Stale values returned from useOptimistic when state changes #57662

dorshinar opened this issue Oct 28, 2023 · 7 comments
Labels
bug Issue was opened via the bug report template. locked Pages Router Related to Pages Router.

Comments

@dorshinar
Copy link

dorshinar commented Oct 28, 2023

Link to the code that reproduces this issue

https://github.com/dorshinar/next-optimistic-bug

To Reproduce

  1. Start application: npm run dev
  2. Observe the rendered array not changing depsite a useEffect setting the state

To illustrate the bug I have a state variable called arrFromServer in the <Form /> component, and I am passing it through useOptimistic as if I was updating data fetched from the server optimistically.
The arrFromServer in a placeholder for data fetched from a Server Component, and the useEffect is a way to simulate updating the data on the server and refetching it.
In the image below, the optimisticArr remains constant with 3 elements, while arrFromServer grows in an interval
Screenshot 2023-10-28 at 12 37 32

Current vs. Expected behavior

I expect useOptimistic to return the up-to-date state passed as parameter while a mutation is not in-flight. The current behavior seems to return the initial state provided to useOptimistic.

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.0.0: Fri Sep 15 14:41:43 PDT 2023; root:xnu-10002.1.13~1/RELEASE_ARM64_T6000
Binaries:
  Node: 20.7.0
  npm: 10.1.0
  Yarn: 1.22.19
  pnpm: 8.9.2
Relevant Packages:
  next: 14.0.1-canary.1
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.1.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Data fetching (gS(S)P, getInitialProps)

Additional context

No response

@dorshinar dorshinar added the bug Issue was opened via the bug report template. label Oct 28, 2023
@github-actions github-actions bot added the Pages Router Related to Pages Router. label Oct 28, 2023
@JesseKoldewijn
Copy link
Contributor

It doesn't,t look like you're using the useOptimistic hook correctly there. (But keep in mind, last time I personally used it it was still experimental)

Maybe try to create a setup just like the official docs show.

https://react.dev/reference/react/useOptimistic

Ps. This is might be better suited in the react repo rather than the Next.js one

@dorshinar
Copy link
Author

Thanks for the reply @JesseKoldewijn!
I might be using it wrong, but as I understand it my example should work. I've tried adding a simple echo function as the second parameter to useOptimistic, but I get the same behavior

const [optimisticArr] = useOptimistic(arrFromServer, (s) => s);

My example intentionally does not use the callback returned from useOptimistic to show that the issue is not about the optimistic update mechanism, but the internal state that useOptimistic apparently holds.

Without a form submission in progress useOptimistic should just pass the state through to my app IIUC.

@JesseKoldewijn
Copy link
Contributor

Thanks for the reply @JesseKoldewijn!

I might be using it wrong, but as I understand it my example should work. I've tried adding a simple echo function as the second parameter to useOptimistic, but I get the same behavior

const [optimisticArr] = useOptimistic(arrFromServer, (s) => s);

My example intentionally does not use the callback returned from useOptimistic to show that the issue is not about the optimistic update mechanism, but the internal state that useOptimistic apparently holds.

Without a form submission in progress useOptimistic should just pass the state through to my app IIUC.

I will have to dig in on the exact behaviour of the useOptimistic hook again but I'll have a look for ya later today👍

@dorshinar
Copy link
Author

dorshinar commented Oct 28, 2023

I think this might indeed be a bug in React. Looking at the code for useOptimistic, specifically this line:
https://github.com/facebook/react/blob/3e09c27b880e1fecdb1eca5db510ecce37ea6be2/packages/react-reconciler/src/ReactFiberHooks.js#L1416

It appears that when both queues are null (pendingQueue and baseQueue), which is, as I understand it, what happens when there are no submissions in progress, the returned value is simply the hook.memoizedState which is, as I suspect, the initial state provided to the hook.

I'll open a bug report in the React repo.

@dorshinar
Copy link
Author

Opened the bug report
facebook/react#27617

@dorshinar
Copy link
Author

This issue has been fixed in React
facebook/react#27617

Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. locked Pages Router Related to Pages Router.
Projects
None yet
Development

No branches or pull requests

2 participants