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() {...}