[cache components]: Client component's state during route navigation #85502
-
|
In Next.js 16, when cacheComponents is enabled, the client component's state is preserved during route navigation. However, when cacheComponents is disabled, the state is lost. What causes this behavior? |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 9 replies
-
|
When Cache Components is enabled, we also wrap Activity components around routes. I just merged the docs update w/ this behavior. Be aware that there's a known issue with Portals. Tracked upstream here: facebook/react#35000 |
Beta Was this translation helpful? Give feedback.
-
|
We're experiencing this Portal issue with shadcn/ui Sidebar (which uses Radix Dialog) in a route group layout scenario: Scenario:
Main UI Bug:
This happens because:
Current Workaround: useEffect(() => {
return () => {
// Wait 500ms for React's async cleanup attempt
setTimeout(() => {
// Manually remove leftover Portal DOM
const sidebarElements = document.querySelectorAll('[data-slot="sidebar"]');
sidebarElements.forEach(element => {
const portalContainer = findPortalContainer(element);
if (portalContainer?.parentNode && document.body.contains(portalContainer)) {
portalContainer.parentNode.removeChild(portalContainer);
}
});
}, 500);
};
}, []);Questions:
@icyJoseph Thanks for the clarification on Cache Components behavior! 🙏 |
Beta Was this translation helpful? Give feedback.
-
|
Is there currently no way to opt out of this? Are there plans to add the option to opt out? |
Beta Was this translation helpful? Give feedback.
-
|
Just saw this been struggling with custom solutions for awhile and could not figure out why my unmounting was not working. This breaks so much existing code it definitely should not be the default. |
Beta Was this translation helpful? Give feedback.
-
|
It’s been a major pain for us as well, and we eventually had to completely opt out of cacheComponents. Our applications have hundreds of dedicated form routes, and once they’re implicitly wrapped in and no longer unmount on navigation, everything breaks from a UX and logic standpoint. It’s not just form state that gets preserved, all useState values are kept alive, even in places where unmounting has always been the natural reset mechanism. A concrete example: With cacheComponents enabled, after that first submit, every future navigation to that same parallel route reuses the stale component state. So instead of opening the dialog again, it instantly triggers the success toast and router.back(), making the dialog impossible to access. The component effectively becomes “stuck” in its previous state forever. Issues like this quickly compound across a large codebase. Retrofitting manual reset logic for hundreds of forms, dialogs, drawers, and components that naturally expect to unmount is simply not realistic. State preservation on navigation can absolutely be useful, but not as an implicit global behavior that requires every component to suddenly become “Activity-aware”. Right now it feels forced on us in a way that breaks long-established patterns, very similar to the aggressive caching in Next 13. I really think this needs to be opt-in, or at least offer a clear and granular opt-out at the route/layout level. These features are powerful, but without an escape hatch they can be extremely disruptive to existing, fully correct application logic. |
Beta Was this translation helpful? Give feedback.
-
|
Want to anecdotally contribute that persisting state between navigation can undesirably leak user data. I've encountered instances wherein a user on the same tab signs in, performs behaviors that are stateful, logs out, and another user logins during that same local session, leads to the recent user being able to see the previous user's existing state. With the mechanisms of react activity when cacheComponents are enabled, developers will need to make significant refactors (in breadth) to ensure sensitive state at the very least is reinitialized appropriately under those circumstances. |
Beta Was this translation helpful? Give feedback.
-
|
Tbh i don’t understand how this continuing to be the default behaviour is even an option. It basically makes cacheComponents unusable on most projects. |
Beta Was this translation helpful? Give feedback.
When Cache Components is enabled, we also wrap Activity components around routes. I just merged the docs update w/ this behavior. Be aware that there's a known issue with Portals. Tracked upstream here: facebook/react#35000