React 上下文提供程序未设置值
React Context Provider not setting value
我正在尝试开始使用 React 上下文挂钩,但我似乎遇到了一个我不明白的问题。
我已经定义了一个用户上下文,它只是一个表示“你好用户”的字符串:
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
然后我尝试访问是这样的:
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
但是即使我在使用 UserContext.Provider
时设置了一个值,也没有打印出任何内容。如果我在创建上下文时指定一个值,但当我通过提供者设置它时没有指定,它将有一个值。
我做错了什么?
您的 Auth
在组件中被调用,但您在 Auth
使用之前调用了 useContext
,这意味着您的上下文 API 尚未初始化
在通常的组件中,您可以使用像
这样的组件包装器来初始化它们
<Context.Provider>
<YourComponent/> // you call `useContext` in `YourComponent`
</Context.Provider>
但在Next.js中,尤其是在page-level组件下,由于代码整洁问题,构建多个ContextAPI并不是一个好方法
我建议您将 Auth
移动到 _app.tsx
,如下所示,这将帮助您在所有 page-level 组件渲染之前初始化上下文 API
export default function MyApp(props: AppProps) {
const { Component, pageProps } = props
return (
<React.Fragment>
<Auth>
<Component {...pageProps} />
</Auth>
</React.Fragment>
)
}
Dash.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
您不能 useContext
在其 Provider
之外。
您需要将 Auth
组件向上移动一个级别,使其包围 Dash
以便使用 const contextMsg = useContext(UserContext)
最终你的 React 组件树应该是这样的:
<Auth>
<Dash />
</Auth>
我正在尝试开始使用 React 上下文挂钩,但我似乎遇到了一个我不明白的问题。
我已经定义了一个用户上下文,它只是一个表示“你好用户”的字符串:
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
然后我尝试访问是这样的:
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
但是即使我在使用 UserContext.Provider
时设置了一个值,也没有打印出任何内容。如果我在创建上下文时指定一个值,但当我通过提供者设置它时没有指定,它将有一个值。
我做错了什么?
您的 Auth
在组件中被调用,但您在 Auth
使用之前调用了 useContext
,这意味着您的上下文 API 尚未初始化
在通常的组件中,您可以使用像
这样的组件包装器来初始化它们<Context.Provider>
<YourComponent/> // you call `useContext` in `YourComponent`
</Context.Provider>
但在Next.js中,尤其是在page-level组件下,由于代码整洁问题,构建多个ContextAPI并不是一个好方法
我建议您将 Auth
移动到 _app.tsx
,如下所示,这将帮助您在所有 page-level 组件渲染之前初始化上下文 API
export default function MyApp(props: AppProps) {
const { Component, pageProps } = props
return (
<React.Fragment>
<Auth>
<Component {...pageProps} />
</Auth>
</React.Fragment>
)
}
Dash.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
您不能 useContext
在其 Provider
之外。
您需要将 Auth
组件向上移动一个级别,使其包围 Dash
以便使用 const contextMsg = useContext(UserContext)
最终你的 React 组件树应该是这样的:
<Auth>
<Dash />
</Auth>