【问题标题】:How do I only wrap some pages in a Context Provider with Next.js?如何使用 Next.js 仅将一些页面包装在 Context Provider 中?
【发布时间】:2021-02-19 14:37:40
【问题描述】:

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

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

例如:

这是我的_app.tsx 的样子:

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

export default function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}

【问题讨论】:

    标签: reactjs react-hooks next.js use-context


    【解决方案1】:

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

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

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

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

    我也会尝试寻找其他解决方案,但请告诉我这对您有用吗。

    【讨论】:

    • 感谢您的建议和帮助我思考这个问题。我希望保留基于文件的路由器,因为它是我非常喜欢 Next.js 的地方之一。我最终只是在上下文中添加了最少量的身份验证信息,并没有像我最初打算的那样共享。
    【解决方案2】:

    我对 Next.js 很陌生,正在寻找同样的问题。 也许我们可以只使用useRouter钩子中的pathnamequery,并在我们的Contexts或自定义_app中尝试一些条件

    next/router

    【讨论】:

      【解决方案3】:

      有一种解决方法可以使用没有 react-router 的包装器来包装特定路径的组件。 看看这个视频: https://www.youtube.com/watch?v=69-mnojSa0M

      该视频向您展示了如何使用嵌套布局包装子路径的组件。创建一个嵌套布局并使用 Context Provider 包装该布局。

      【讨论】:

        【解决方案4】:

        聚会有点晚了,但实际上有一种官方方法可以做到这一点: 使用per page layout。 首先稍微调整一下你的_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} />);
        };
        

        然后在页面组件中编写以下内容:

        // 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;
        
        

        【讨论】:

        • 嗨,这真的会保留页面之间的上下文值吗?例如。当您登录时,您的UserProvider 中有用户并且您导航到使用相同布局的其他页面,我怀疑用户会留在上下文中,对吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-01
        • 2011-03-04
        • 2020-01-23
        • 1970-01-01
        • 2011-07-27
        • 1970-01-01
        相关资源
        最近更新 更多