我想在三个页面之间共享数据(这些是网络应用程序的核心),但我还有一堆不关心这些数据的博客页面。我看过的所有地方都建议将提供程序放入
_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} />
}
聚会有点晚了,但实际上有一个官方方法可以做到这一点: 使用每页布局。 首先稍微调整你的
_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;
嗯,这是一个有趣的问题。
挑战在于 Next 实现基于文件的路由的方式。由于无法为页面组创建包装器,因此您唯一能做的就是将应用程序包装在上下文提供程序中。但这并不能真正解决您的问题。
SOOO...我认为有一个解决方法。如果您希望能够在上下文提供程序中包装特定的一组页面,首先,您需要将基于文件的路由器替换为react-router。
Andrea Carraro 有一篇关于这个主题的非常有趣的文章。我认为你应该尝试一下: https://dev.to/tooomuchdesign/next-js-react-router-2kl8
我也会尝试寻找另一种解决方案,但请告诉我这对你有用吗。
有一种解决方法可以使用包装器包装特定路径的组件,而无需使用反应路由器。 看看这个视频: https://www.youtube.com/watch?v=69-mnojSa0M
该视频向您展示了如何使用嵌套布局包装子路径的组件。创建一个嵌套布局并使用您的上下文提供程序包装该布局。
我对 Next.js 很陌生,正在寻找同样的问题。 也许我们可以只使用
pathname
钩子中的 query
和 useRouter
并在我们的 Contexts
或自定义 _app
中尝试一些条件语句
很晚才回答我的问题,但我的方法可能会对将来的某人有所帮助。 我使用页面作为包装器,并使用查询参数进行导航。
例如
我使用 contextProvider 并检查 _app.js 中的路径页面
myContextProvider.js
import React, { useState } from 'react';
const Context = React.createContext({});
export function myContextProvider({ children }) {
const [ state1, setState1 ] = useState(true);
return <Context.Provider value={{ state1, setState1 }}>
{children}
</Context.Provider>;
}
export default Context;
_app.js
import { useRouter } from 'youreFavoRouter';
import { myContextProvider } from './myContextProvider.js';
export default function MyApp({ Component, pageProps }) {
const router = useRouter();
const isBlogPage = router.pathname.includes('blog');
return (
<div>
{isBlogPage ? (
<Component {...pageProps} />
) : (
<myContextProvider>
<Component {...pageProps} />
</myContextProvider>
)}
</div>
);
}
现在 myContextProvider 上的所有状态和函数都可以在您选择的页面上查看和使用。 我希望能帮助任何人。 :)
嘿,我想我应该发布这个我发现到目前为止对我有用的解决方案。我想也许我可以将我的上下文导入到我的一个页面中,并测试用它包装提供程序是否可行。我也是 Nextjs 的新手,不知道这是否是一种合理的方法,但它似乎对我有用。我可以从我的 [用户名].tsx 页面中的这个组件用户配置文件访问我提供的所有内容。
如果这不是一个好的方法,任何反馈都会有用。
// pages/[username].tsx
import { UserProfile } from '@component/app/userprofile';
const UserPage = () => {
const router = useRouter();
const { username } = router.query;
useEffect(() => {
console.log('Username:', username);
}, [username]);
return (
<SampleContextProviderComponent>
{user && user.map((user, index) => {
if(username === user.username){
return <UserProfile key={index} user={user}/>
}
})}
</SampleContextProviderComponent>
);
};
export default UserPage;