在next js中将一个变量从Layout传递给子节点



我有以下代码'

import { useState, useEffect } from 'react'
import LayoutContent from './layout_content';
type Props = {
children: JSX.Element | JSX.Element[]
}
const Layout = ({ children }: Props) => {
const [selected, setSelected] = useState(countries[0]);
const country= selected.id
return (
<>
<Sidebar onClick={toggle} sidebar={open} />
<LayoutContent sidebar={open} countriesWithsrc ={countriesWithsrc}  selected={selected} lected={setSelected} >
{children}
</LayoutContent>
</>
)
}
export default Layout;

'如何将变量国家从布局组件传递到没有状态管理的子组件?我想钻它。

一个重要的细节是,如果子页面在服务器端呈现,我们在props中有searchParams和params(至少到当前版本的NextJs 13.2)…例如:

const Page = async ({searchParams, params}: {
searchParams: { [key: string]: string | string[] | undefined },
params: {language: string} 
}) => { 
console.log('current locale:', params.language);
console.log('your query param:', searchParams['yourParam'])
....
}

好看!

如果您不需要任何状态管理,您可以使用React.Children。它提供了与childrenprop一起工作的实用程序。React.Children.map将为组件的每个直接子组件运行一个方法。您可以使用cloneElement和它一起通过传递额外的属性来创建元素的克隆。事实上,您甚至可以修改正在克隆的元素的子元素,但这不是这里的问题。

请注意上下文将是更好的方法。


const Layout = ({ children }: Props) => {
....
....
const modifiedChildren = React.Children.map(children, child => {
if (React.isValidElement(child)) {
return React.cloneElement(child, { testProp : 'test' });
}
return child;
});
....
....
return (
<>
<Sidebar onClick={toggle} sidebar={open} />
<LayoutContent sidebar={open} countriesWithsrc ={countriesWithsrc}  selected={selected} lected={setSelected} >
{modifiedChildren}
</LayoutContent>
</>
)
}

你可以通过使用React Context API来实现。

首先创建上下文:

// context.ts
import { createContext } from "react";
interface LayoutContextProps {
country: number | undefined; // undefined, because I assume there's no initial value for country
setCountry?: React.Dispatch<React.SetStateAction<number>>; // You could also pass a setter if needed.
}
export const LayoutContext = createContext<LayoutContextProps>({
country: undefined, // Based on the assumption that they may be no known initial value.
setCountry: () => {}, // Assuming you're passing a setter
});

接下来,用上下文包装布局并提供值。

// layout.tsx
import { useState, useEffect } from "react";
import { LayoutContext } from "./context";
type Props = {
children: JSX.Element | JSX.Element[];
};
const Layout = ({ children }: Props) => {
const [selected, setSelected] = useState(countries[0]);
const country = selected.id;
return (
<LayoutContext.Provider value={{ country }}>
<Sidebar onClick={toggle} sidebar={open} />
<LayoutContent
sidebar={open}
countriesWithsrc={countriesWithsrc}
selected={selected}
lected={setSelected}
>
{children}
</LayoutContent>
</LayoutContext.Provider>
);
};
export default Layout;
现在,您可以访问布局的子组件中的上下文值了。
import { useContext } from "react";
import { LayoutContext } from "./context";
export default function ChildComponent() {
const { country } = useContext(LayoutContext); // You may need to check if value if not undefined; up to you.
return <div>Country ID: {country}</div>;
}

我通常是这样做的。

最新更新