nextjs - 💡(How to fix) Fix useLayoutEffect context update causes local state reset in React 19 [4 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#89052Fetched 2026-04-08 02:03:24
View on GitHub
Comments
4
Participants
3
Timeline
10
Reactions
0
Assignees
Timeline (top)
commented ×4assigned ×1closed ×1labeled ×1

Fix Action

Workaround

Change useLayoutEffect to useEffect and wrap context updates in startTransition:

useEffect(() => {
  startTransition(() => {
    context?.setContent(content);
  });
  return () => {
    startTransition(() => {
      context?.setContent(null);
    });
  };
}, [context, content, updateKey]);

Code Example

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.3.0

Binaries:
  Node: 22.x
  npm: 10.x

Relevant Packages:
  next: 16.1.1-canary.4
  react: 19.0.0
  react-dom: 19.0.0

Turbopack: Enabled

---

Click: setIsEditing(true)
Render: true    // Good - state changed!
Render: false   // BAD - state reset!

---

useEffect(() => {
  startTransition(() => {
    context?.setContent(content);
  });
  return () => {
    startTransition(() => {
      context?.setContent(null);
    });
  };
}, [context, content, updateKey]);
RAW_BUFFERClick to expand / collapse

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 25.3.0

Binaries:
  Node: 22.x
  npm: 10.x

Relevant Packages:
  next: 16.1.1-canary.4
  react: 19.0.0
  react-dom: 19.0.0

Turbopack: Enabled

Which area(s) are affected?

App Router, Turbopack

Link to the code that reproduces this issue

https://github.com/jpoindexter/nextjs-useLayoutEffect-state-reset

To Reproduce

  1. Clone the repo: git clone https://github.com/jpoindexter/nextjs-useLayoutEffect-state-reset
  2. npm install
  3. npm run dev
  4. Open http://localhost:3000
  5. Open browser console
  6. Click the "EDIT" button

Describe the Bug

When a component uses useLayoutEffect to update React Context state (via a custom hook), and the component triggers a local state change, the local state appears to "reset" during the render cascade.

Console output on first click:

Click: setIsEditing(true)
Render: true    // Good - state changed!
Render: false   // BAD - state reset!

The context correctly receives the new state (right rail shows "EDIT MODE ACTIVE" briefly), but the component's local state reverts to its previous value.

Expected Behavior

  • isEditing becomes true and stays true
  • The edit form appears
  • Console shows only: Render: true

Actual Behavior

  • isEditing briefly becomes true, then resets to false
  • The edit form does NOT appear
  • Console shows true then false

Workaround

Change useLayoutEffect to useEffect and wrap context updates in startTransition:

useEffect(() => {
  startTransition(() => {
    context?.setContent(content);
  });
  return () => {
    startTransition(() => {
      context?.setContent(null);
    });
  };
}, [context, content, updateKey]);

Additional Context

  • This bug does NOT occur in React 18
  • Page refresh works correctly (component mounts fresh with correct state)
  • The issue is specific to state transitions during useLayoutEffect context updates

extent analysis

TL;DR

Change useLayoutEffect to useEffect and wrap context updates in startTransition to prevent the local state reset issue.

Guidance

  • Verify that the issue is specific to the combination of useLayoutEffect and Turbopack by testing with useEffect and disabling Turbopack.
  • Check if the issue persists in a non-canary release of Next.js to determine if it's a regression.
  • Test the provided workaround in the reproduction repository to confirm its effectiveness.
  • Consider updating React to the latest version to see if the issue is resolved, given that it does not occur in React 18.

Example

The provided workaround code snippet demonstrates how to modify the useLayoutEffect hook to use useEffect with startTransition:

useEffect(() => {
  startTransition(() => {
    context?.setContent(content);
  });
  return () => {
    startTransition(() => {
      context?.setContent(null);
    });
  };
}, [context, content, updateKey]);

Notes

The issue appears to be specific to the combination of useLayoutEffect, Turbopack, and React 19. The provided workaround may not be the only solution, and further investigation may be necessary to determine the root cause.

Recommendation

Apply the workaround by changing useLayoutEffect to useEffect and wrapping context updates in startTransition, as this has been shown to resolve the issue in the provided reproduction repository.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

nextjs - 💡(How to fix) Fix useLayoutEffect context update causes local state reset in React 19 [4 comments, 3 participants]