我知道搜索参数可以在页面组件属性中访问,但是同一路由段内的深层嵌套的非页面服务器组件也可以以某种方式访问搜索参数吗?例如,让我们假设一个场景。我们有以下组件结构:
RouteSegmentPage
ServerComponentLevel1
...
ServerComponentLevelN
LeafClientComponent
AnotherRouteSegmentPage
...
RouteSegmentPage
显示一个丰富的页面,其中包含许多嵌套的非页面子组件,所有组件都位于同一路由段中。 ServerComponentLevelN
需要使用搜索参数获取一些数据。如果没有从 RouteSegmentPage
一直到 ServerComponentLevelN
的道具钻探搜索参数,我们如何才能实现这一目标?
注意:
ServerComponentLevelN
需要保留为服务器组件。
直到今天,Next.js 团队似乎还没有想出任何优雅的方法来实现这一目标(这对我来说有点疯狂,因为我认为深入访问查询参数和路径参数-嵌套 RSC 是一个非常常见的用例)。
无论如何,使用 React Cache 有一个相对简洁的解决方法:
import { cache } from 'react';
const getStore = cache(() => ({ value: '' }));
export const getValue = () => getStore().value;
export const setValue = (value: string) => {
getStore().value = value;
};
然后在您的
page.tsx
中调用 setValue(props.searchParams.value)
,并在深度嵌套的子服务器组件中使用 getValue()
将其取回。
也适用于路径参数(对于路径参数,您也可以在
setValue
组件中调用 layout.tsx
)
或者,您可以尝试在
middleware.ts
中添加所需的参数作为自定义请求标头。然后,您可以使用 Next.js headers
函数在任何 RSC 中访问它。
在这里找到了解决方法 https://github.com/vercel/next.js/discussions/51818 作者:icy约瑟夫
解决方法是基本上避免使用钩子,并坚持只使用js。
// app/store.tsx
const createStore = () => {
let data: string | null = null;
const setData = (next: string) => {
data = next;
};
const getData = () => {
return data;
};
return { setData, getData };
};
export const store = createStore();
// app/[foo]/[bar]/page.tsx
import { Outer } from "../../Outer";
import { store } from "../../store";
export default function Page({
params,
}: {
params: { foo: string; bar: string };
}) {
const { foo, bar } = params;
store.setData(`/${foo}/${bar}`);
return <Outer />;
}
import { store } from "./store";
export const Inner = () => {
return <div>{store.getData()}</div>;
};