React Context Provider 未设置值

Aar*_*n56 3 typescript reactjs next.js use-context

我正在尝试开始使用 React 上下文挂钩,但我似乎遇到了一个我不明白的问题。

我定义了一个用户上下文,它只是一个表示“hello user”的字符串,如下所示:

import { useContext, createContext } from "react"

export const UserContext = createContext<string | null>(null)

export interface IAuth {
  children: React.ReactNode;
}

const Auth: React.FC<IAuth> = (props) => {

  return(
    <UserContext.Provider value={"hello user"}>
      {props.children}
    </UserContext.Provider>
  )
}

export default Auth
Run Code Online (Sandbox Code Playgroud)

然后我尝试访问是这样的:

const Dash: NextPage<dashPageProps> = (props) => {

  const contextMsg = useContext(UserContext)

  const submitForm = () => {
    console.log("logout")
  }

  return (
    <Auth>
    <div className="w-screen">
      <div className='text-xl'>
        Dashboard
      </div>
      <h1>{contextMsg}</h1>
      <button className='bg-gray-400 border-2 border-gray-600 w-fit mt-5' onClick={submitForm} >Log out</button>
    </div>
    </Auth>
  )
}

export default Dash
Run Code Online (Sandbox Code Playgroud)

但即使我在使用时设置了一个值,也没有打印出任何内容UserContext.Provider。如果我在创建上下文时指定一个值,但在通过提供程序设置它时则不指定,它将具有一个值。

我在这里做错了什么?

Nic*_* Vu 6

Auth是在组件内调用的,但您在使用useContext之前调用Auth,这意味着您的 Context API 尚未初始化

在通常的组件中,您可以使用组件包装器来初始化它们,例如

<Context.Provider>
  <YourComponent/> // you call `useContext` in `YourComponent`
</Context.Provider>
Run Code Online (Sandbox Code Playgroud)

但在 Next.js 中,尤其是在页面级组件下,由于代码整洁的问题,构建多个 Context API 并不是一个好方法

我建议您应该将您的Auth内容移至_app.tsx如下所示,这将帮助您在所有页面级组件的渲染之前初始化 Context API

export default function MyApp(props: AppProps) {
  const { Component, pageProps } = props

  return (
    <React.Fragment>
      <Auth>
        <Component {...pageProps} />
      </Auth>
    </React.Fragment>
  )
}
Run Code Online (Sandbox Code Playgroud)

达世币.tsx

const Dash: NextPage<dashPageProps> = (props) => {

  const contextMsg = useContext(UserContext)

  const submitForm = () => {
    console.log("logout")
  }

  return (
    <div className="w-screen">
      <div className='text-xl'>
        Dashboard
      </div>
      <h1>{contextMsg}</h1>
      <button className='bg-gray-400 border-2 border-gray-600 w-fit mt-5' onClick={submitForm} >Log out</button>
    </div>
  )
}

export default Dash
Run Code Online (Sandbox Code Playgroud)