如何使用 Next.js 仅将某些页面包装在 Context Provider 中?

mpc*_*c75 6 reactjs next.js react-hooks use-context

我想在三个页面之间共享数据(这些是 Web 应用程序的核心),但我也有一堆不关心这些数据的博客页面。我看过的所有地方都建议将 Provider 放在_app.tsx文件中。如果我对MyApp提供者的理解正确,如果有人直接访问www.myurl.com/blog/my-blog-1(来自 google),这将导致提供者运行其功能;即使该页面不会调用 useContext

如何只在 Provider 中包装三页而忽略博客页面?

例如:

这是我的_app.tsx样子:

import { AppProps } from 'next/app'
import '../styles/index.css'

export default function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}
Run Code Online (Sandbox Code Playgroud)

Mr *_*ton 10

虽然有点晚了,但实际上有一种官方方法可以做到这一点:使用每页布局。首先稍微调整一下你的_app.tsx文件:

import type { ReactElement, ReactNode } from 'react';
import { AppProps } from 'next/app';
import type { NextPage } from 'next';

type NextPageWithLayout = NextPage & {
    getLayout?: (page: ReactElement) => ReactNode;
};

type AppPropsWithLayout = AppProps & {
    Component: NextPageWithLayout;
};
export const App = ({ Component, pageProps }: AppPropsWithLayout): unknown => {

    // Use the custom layout defined at the page level, if available
    const getLayout = Component.getLayout ?? ((page) => page);

    return getLayout(<Component {...pageProps} />);
};
Run Code Online (Sandbox Code Playgroud)

然后在 Page 组件中写入以下内容:

// DashboardPage.ts that need to have a UserProvider and CompanyProvider
import Layout from '@components/Layout'; // Default Layout that is imported for all the page
import { ReactElement } from 'react';
import { UserProvider } from '@contexts/user';
import { CompanyProvider } from '@contexts/company';

const DashboardPage = (): JSX.Element => {
    return <DashboardContainer />;
};

// Custom Layout to wrap the page within the User and company providers
DashboardPage.getLayout = function getLayout(page: ReactElement) {
    return (
        <Layout title="Dashboard page">
            <UserProvider>
                <CompanyProvider>{page}</CompanyProvider>
            </UserProvider>
        </Layout>
    );
};

export default DashboardPage;

Run Code Online (Sandbox Code Playgroud)

  • 你好,这真的能保留页面之间的上下文值吗?例如,当您登录时,您的“UserProvider”中有用户,并且导航到使用相同布局的其他页面,我怀疑用户是否会留在上下文中,不是吗? (2认同)
  • 对于遇到这种情况的任何人来说,这都有效!我有一个多页 Formik 表单,仅与我的应用程序的子目录有关。管理上下文的 &lt;Formik&gt; 标签位于我的布局使用的包装组件中。我确认,当我使用此布局在页面之间导航时,上下文会被保留。正如文档所说:“这种布局模式可以实现状态持久化,因为 React 组件树是在页面转换之间维护的。” 通过组件树,React 可以了解哪些元素已更改以保留状态。 (2认同)

Dej*_*dic 3

嗯,这是一个有趣的问题。

挑战在于 Next 实现基于文件的路由的方式。由于无法为页面组创建包装器,因此您唯一能做的就是将应用程序包装在上下文提供程序中。但这并不能真正解决你的问题。

SOOO...我认为有一个解决方法。如果您希望能够在上下文提供程序中包装特定的一组页面,首先,您需要将基于文件的路由器替换为react-router。

Andrea Carraro 有一篇关于这个主题的非常有趣的文章。我认为你应该尝试一下: https ://dev.to/toomuchdesign/next-js-react-router-2kl8

我也会尝试寻找另一种解决方案,但请告诉我这对您有用吗?