在哪里使用应用程序路由器在 NextJS 13 中添加上下文提供程序?

Where do I add Context Provider in NextJS 13 using app router?

提问人:Andrew Chung 提问时间:11/17/2023 更新时间:11/17/2023 访问量:14

问:

在 React 中,你有这样的东西:

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";

import App from "./App";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </StrictMode>
);

你会把你的提供程序包装在 但是在 NextJS v13.4+ 中,这 ' 不存在。创建全局可用上下文的正确方法是什么?<App />app router

此外,在导入要在 中使用的第三方库时,我认为 useEffect/useState 之类的东西会产生问题。有没有办法在创建一个?contextcontext provider

reactjs next.js vercel next.js13

评论


答:

0赞 Octo Palm Tree 11/17/2023 #1

好问题,我很高兴你问。

这是我是如何做到的。让我们从向上和向下钻取的“结束”开始。(然后我们将看看如何使用它们,即如何获取/设置变量。Pages

因此,您将改用 RootLayout,而不是在根元素处呈现。这确实是由 NextJS 创建的,并存在于这里:<App />/App/layout.js

import './globals.css';
import { Providers } from './ContextProviders/Providers';

export default function RootLayout({ children }) {
    return (
        <html>
            <body>
                <Providers>{children}</Providers>
            </body>
        </html>
    );
}

好的^,现在这是您的包装器,您可以在其中导入自己的提供商或第三方提供商。<Providers>

让我们看看如何定义 .请注意表示法,以防止在服务器组件上使用“客户端”第三方库时出现问题。请注意多个提供程序应如何连续相互包装。我把这个放在这里:.<Providers />'use client'/app/ContextProviders

'use client';

import { UserProvider } from './UserProvider';
import { MyOtherProvider } from './MyOtherProvider';

export function Providers({ children }) {
    return <MyOtherProvider><UserProvider>{children}</UserProvider></MyOtherProvider>;


}

最后,让我们看看如何创建提供程序。

import React, { createContext, useEffect, useState } from 'react';

export const UserContext = createContext();

export const UserProvider = ({ children }) => {
    const [userID, setUserID] = useState('');

    useEffect(() => {
        // do stuff like setting userID
        // you might access a db or other service here
        setUserID('asdfasdf-asdf-asdf-asdf-asdfasdfasdf');
    }, []);

    return <UserContext.Provider value={{ userID, setUserID }}>{children}</UserContext.Provider>;
};

如果你对为什么 value 有双大括号感到困惑,它只是通过使用键值对(即对象文字)赋值在代码中创建对象的简写。换句话说,用较少的句法糖是这样的:

return <UserContext.Provider value={{ userID: userID, setUserID: setUserID }}>{children}</UserContext.Provider>;

或者更明确地说,这是:

const sharedValues = 
{ userID: userID, setUserID: setUserID }

return <UserContext.Provider value={sharedValues}>{children}</UserContext.Provider>;



那么,我们如何在页面中使用它呢?

// /app/page.js
import react, { useContext } from 'react';
import UserContext from './ContextProviders/UserProvider'

export default Page() {

const { userID, setUserID } = useContext(UserContext);

return (<div>Hello World! {userID} </div>)
}

如果您想了解更多关于 Vercel 团队的信息,请看这里