admin管理员组文章数量:1194134
A common use case I run across is having a button in a layout toggle something in the children. For example, you could have a notifications button in a persisted layout that opens a side pane in the main app.
Ideally, you would be able to pass an isNotificationsPaneOpen
state down to the children and have them render the pane. However,the Next 13 beta docs say this isn't possible:
Passing data between a parent layout and its children is not possible. However, you can fetch the same data in a route more than once, and React will automatically dedupe the requests without affecting performance.
Persisting this toggle state in the backend seems like a major overkill and feels unnatural. The backend shouldn't have to know about the frontend opening or closing a notifications panel.
It seems to me that this is a common enough use case that people will run into this issue often.
How should one generally think about this?
Concrete example:
// in layout.tsx
export default function NavbarLayout({
children,
}: {
children: React.ReactNode,
}) {
const [isNotificationsPaneOpen, setIsNotificationsPaneOpen]= useState(false);
return (
<div>
<nav>
<button onClick={()=>setIsNotificationsPanelOpen((prevValue)=>!prevValue)}>Notifications</button>
</nav>
{/* How do I pass isNotificationsPaneOpen to children? */}
{children}
</div>
);
}
So that in the page:
// in page.tsx
interface PageProps {
isNotificationsPaneOpen: boolean;
}
function Page({isNotificationsPaneOpen}:PageProps):JSX.Element {
// render something conditionally with isNotificationsPaneOpen
...
}
Current solutions
- Include the pane to toggle in the layout (best candidate IMO)
If the component that depends on the layout's state remains the same across pages (like the notifications panel example), it makes sense to include it here. But other examples - like toggling light/dark mode in the layout - render different things on each page so this is not a general solution.
- External storage like
localstorage
to pass data
More of a hack but you could have the layout send data to an external data source (ideally within the browser) and then query that data source from the main app to determine if the panel should be open or not.
A common use case I run across is having a button in a layout toggle something in the children. For example, you could have a notifications button in a persisted layout that opens a side pane in the main app.
Ideally, you would be able to pass an isNotificationsPaneOpen
state down to the children and have them render the pane. However,the Next 13 beta docs say this isn't possible:
Passing data between a parent layout and its children is not possible. However, you can fetch the same data in a route more than once, and React will automatically dedupe the requests without affecting performance.
Persisting this toggle state in the backend seems like a major overkill and feels unnatural. The backend shouldn't have to know about the frontend opening or closing a notifications panel.
It seems to me that this is a common enough use case that people will run into this issue often.
How should one generally think about this?
Concrete example:
// in layout.tsx
export default function NavbarLayout({
children,
}: {
children: React.ReactNode,
}) {
const [isNotificationsPaneOpen, setIsNotificationsPaneOpen]= useState(false);
return (
<div>
<nav>
<button onClick={()=>setIsNotificationsPanelOpen((prevValue)=>!prevValue)}>Notifications</button>
</nav>
{/* How do I pass isNotificationsPaneOpen to children? */}
{children}
</div>
);
}
So that in the page:
// in page.tsx
interface PageProps {
isNotificationsPaneOpen: boolean;
}
function Page({isNotificationsPaneOpen}:PageProps):JSX.Element {
// render something conditionally with isNotificationsPaneOpen
...
}
Current solutions
- Include the pane to toggle in the layout (best candidate IMO)
If the component that depends on the layout's state remains the same across pages (like the notifications panel example), it makes sense to include it here. But other examples - like toggling light/dark mode in the layout - render different things on each page so this is not a general solution.
- External storage like
localstorage
to pass data
More of a hack but you could have the layout send data to an external data source (ideally within the browser) and then query that data source from the main app to determine if the panel should be open or not.
Share Improve this question edited May 1, 2023 at 9:19 Youssouf Oumar 45.8k16 gold badges98 silver badges103 bronze badges asked Jan 25, 2023 at 19:29 MauroNeiraMauroNeira 4451 gold badge4 silver badges15 bronze badges 1 |1 Answer
Reset to default 22I think your question is the result of a misconception of what a layout
is for within the app
router (directory) of Next.js 13
.
It's supposed to be just an "UI that is shared between multiple pages" of a route segment (page.js
, loading.js
, etc.).
And, as you mentioned, they say:
Passing data between a parent layout and its children is not possible. However, you can fetch the same data in a route more than once, and React will automatically dedupe the requests without affecting performance.
This is because a layout
is not a global state provider. For this need consider using already known technics, for example, a context
. Find below an example of sharing a theme:
// app/theme-provider.js
'use client';
import { createContext, useContext } from 'react';
const ThemeContext = createContext();
export function useThemContext(){
return useContext(ThemeContext);
}
export default function ThemeProvider({ children }) {
return (
<ThemeContext.Provider value="dark">
{children}
</ThemeContext.Provider>
);
}
// app/layout.js
import ThemeProvider from './theme-provider';
export default function RootLayout({ children }) {
return (
<html>
<body>
<ThemeProvider>{children}</ThemeProvider>
</body>
</html>
);
}
// app/component.js
"use client";
import { useThemContext } from "./theme-provider";
export default function Component() {
const theme = useThemContext();
// ...
}
本文标签: javascriptHow to pass data from a layout to the children in the app folder of NextjsStack Overflow
版权声明:本文标题:javascript - How to pass data from a layout to the children in the app folder of Next.js? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738498756a2090142.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
React.createElement
as well, I guess? – Arpit Bhalla Commented May 1, 2023 at 9:25