vercel / next.js

The React Framework
https://nextjs.org
MIT License
127.08k stars 27.01k forks source link

redux context in root layout not applying to sub page layouts #49557

Open temrb opened 1 year ago

temrb commented 1 year ago

Verify canary release

Provide environment information

nextjs latest / stable

Which area(s) of Next.js are affected? (leave empty if unsure)

layouts / app router

Link to the code that reproduces this issue

https://github.com/wpcodevo/nextjs13-redux-toolkit/tree/main

To Reproduce

create sub page layouts that uses redux with redux context wrapping children in root layout.

Describe the Bug

for context, I am using this repo to get redux up and running my app router/ next 13 stable project:

https://github.com/wpcodevo/nextjs13-redux-toolkit/tree/main

issue: I have context wrapped in root layout, though have page layouts.

Screenshot 2023-05-09 at 6 36 39 PM Screenshot 2023-05-09 at 6 37 31 PM

The root layout here contains the redux provider as seen above

When I try to have redux dispatch / selectors in page layouts, I get errors:

Screenshot 2023-05-09 at 6 35 27 PM

In this case, I have a plan-layout for the plan page with selectors. I should not need a second provider in plan layout for this to work as I already have a provider in the root layout. If i add a temprorary provider in my plan-page layout, the error seems to go away.

Expected Behavior

context that is applied in root layout should be applied to all sub page layouts as described in the docs : "If you were to combine the two layouts above, the root layout (app/layout.js) would wrap the dashboard layout "

In this case, the redux context would wrap around the page layouts.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

zibranA commented 1 year ago

Facing same issue when using useAppDispatch exported from redux store

temrb commented 1 year ago

I see there has been discussions on this regarding context not showing up on #41994 as well since oct 2022.

Hope this can get fixed soon!

sannajammeh commented 1 year ago

Have you placed your redux provider in a wrapper component with "use client" directive? Otherwise it won't work properly as Redux requires context, which is not available in RSC.

temrb commented 1 year ago

yes-- I have a "providers" component that looks like this:

https://github.com/wpcodevo/nextjs13-redux-toolkit/blob/main/src/redux/provider.tsx

has use client in that wraps around all children in root. this results in issue with context

OhKai commented 1 year ago

I just ran into a similar problem where a theme provider in the root layout would have no effect on the server-rendered output of my page that is marked with "use client". Even though the layout would log to be rendered on a hard reload, the page would render as if it were the root component and not "see" any of the client components in the layout above.

The solution was to refactor my page component to be a Server Component again (removing "use client") and simply return a client component that was marked as "use client" containing the code previously inpage.tsx.

export default function Page() {
  return <ClientComponent />;
}
"use client";
export default function ClientComponent() {
  const theme = useTheme();
  // theme now has correct value when SSR
  return <div />;
}

Note: Since the server component is not dynamic, it will only be run during the build and won't require a server. So static export should still work.

zibranA commented 1 year ago

Thanks for sharing this solution. Does it mean ‘use client’ is not working in page files

temrb commented 1 year ago

I tried out @OhKai solution, though I get context errors in terminal when hard reloading / or reloading / loading the specific page with redux.

For "The solution was to refactor my page component to be a Server Component again" Layout is already default as server so making page component server is kind of redundant I think.

I ended up not using redux all together and went with zustand for the time being. Currently all refactored state code works due to zustand not needing a context wrapper

OhKai commented 1 year ago

For "The solution was to refactor my page component to be a Server Component again" Layout is already default as server so making page component server is kind of redundant I think.

To be clear, what worked for me was turning my page.tsx from a client component ("use client" at top) to a server component (no "use client" instead import with "use client"). I am not talking about layout.tsx here, that was always a server component.

And I don't think it is redudant, in fact, in production on client navigations, your layout won't even be rendered on the server, just the page. They are pretty independent so that the layout can serve multiple pages without rerendering.

Shriansh2002 commented 1 year ago

Use the latest nextjs version next: "13.4.12" It is working for me.

My folder structure:

Screenshot 2023-07-23 at 12 46 55 PM
sechibueze commented 1 year ago

Please what's the update on this issue as I'm currently encountering it.

temrb commented 1 year ago

Refer to nextjs's example

https://github.com/vercel/next.js/tree/canary/examples/with-redux

Though I recommend just going with zustand to avoid headaches