Next.js 的每页布局组件未从 Vercel 的 swr 全局配置中获取值
Next.js's per page layout component doesn't get value from Vercel's swr global configuration
如果我明确输入 fetcher,来自 swr 的 useSWR
钩子在任何地方都有效。
const { data } = useSWR("http://...", fetcher);
但是,如果我使用如下所示的 swr 全局配置,useSWR
仅在 First
页面中有效,但在 HeaderLayout
组件中无效。我做了一些调试,发现在 HeaderLayout
中没有从 swr 全局配置(SWRConfig
在 _app.tsx
中)接收值,即使它被包裹在里面。
我按照此文档 https://nextjs.org/docs/basic-features/layouts#per-page-layouts 进行页面布局实施
// _app.tsx
type NextPageWithLayout = NextPage & {
getLayout?: (page: React.ReactElement) => React.ReactNode;
};
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const getLayout = Component.getLayout ?? ((page) => page);
return (
<SWRConfig
value={{
fetcher: (resource, init) =>
fetch(resource, init).then((res) => res.json()),
}}
>
{getLayout(<Component {...pageProps} />)}
</SWRConfig>
);
}
// pages/first
const First = () => {
const [searchInput, setSearchInput] = useState("");
const router = useRouter();
const { data } = useSWR("http://...");
return (
<div>...Content...</div>
);
};
First.getLayout = HeaderLayout;
// layout/HeaderLayout
const HeaderLayout = (page: React.ReactElement) => {
const router = useRouter();
const { project: projectId, application: applicationId } = router.query;
const { data } = useSWR(`http://...`);
return (
<>
<Header />
{page}
</>
);
};
有用的链接:
https://nextjs.org/docs/basic-features/layouts#per-page-layouts
https://swr.vercel.app/docs/global-configuration
您的 First.getLayout
属性 应该是一个接受 page
和 returns 由 HeaderLayout
组件包装的页面的函数。
First.getLayout = function getLayout(page) {
return (
<HeaderLayout>{page}</HeaderLayout>
)
}
HeaderLayout
是一个 React 组件,它的第一个参数包含传递给它的 props
。您需要稍微修改其签名以匹配它。
const HeaderLayout = ({ children }) => {
const router = useRouter();
const { project: projectId, application: applicationId } = router.query;
const { data } = useSWR(`http://...`);
return (
<>
<Header />
{children}
</>
);
};
如果您将 Page 声明为 const,布局将不起作用。所以代替 const First = () => {...}
做 function First() {...}
如果我明确输入 fetcher,来自 swr 的 useSWR
钩子在任何地方都有效。
const { data } = useSWR("http://...", fetcher);
但是,如果我使用如下所示的 swr 全局配置,useSWR
仅在 First
页面中有效,但在 HeaderLayout
组件中无效。我做了一些调试,发现在 HeaderLayout
中没有从 swr 全局配置(SWRConfig
在 _app.tsx
中)接收值,即使它被包裹在里面。
我按照此文档 https://nextjs.org/docs/basic-features/layouts#per-page-layouts 进行页面布局实施
// _app.tsx
type NextPageWithLayout = NextPage & {
getLayout?: (page: React.ReactElement) => React.ReactNode;
};
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const getLayout = Component.getLayout ?? ((page) => page);
return (
<SWRConfig
value={{
fetcher: (resource, init) =>
fetch(resource, init).then((res) => res.json()),
}}
>
{getLayout(<Component {...pageProps} />)}
</SWRConfig>
);
}
// pages/first
const First = () => {
const [searchInput, setSearchInput] = useState("");
const router = useRouter();
const { data } = useSWR("http://...");
return (
<div>...Content...</div>
);
};
First.getLayout = HeaderLayout;
// layout/HeaderLayout
const HeaderLayout = (page: React.ReactElement) => {
const router = useRouter();
const { project: projectId, application: applicationId } = router.query;
const { data } = useSWR(`http://...`);
return (
<>
<Header />
{page}
</>
);
};
有用的链接:
https://nextjs.org/docs/basic-features/layouts#per-page-layouts
https://swr.vercel.app/docs/global-configuration
您的 First.getLayout
属性 应该是一个接受 page
和 returns 由 HeaderLayout
组件包装的页面的函数。
First.getLayout = function getLayout(page) {
return (
<HeaderLayout>{page}</HeaderLayout>
)
}
HeaderLayout
是一个 React 组件,它的第一个参数包含传递给它的 props
。您需要稍微修改其签名以匹配它。
const HeaderLayout = ({ children }) => {
const router = useRouter();
const { project: projectId, application: applicationId } = router.query;
const { data } = useSWR(`http://...`);
return (
<>
<Header />
{children}
</>
);
};
如果您将 Page 声明为 const,布局将不起作用。所以代替 const First = () => {...}
做 function First() {...}