I am trying to get started with React context hooks and I seem to be having an issue I dont understand.
I have defined a user context that is simply a string that says "hello user" as such:
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
Then I am attempting to access is like this:
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
But nothing is being printed out even though I have set a value when using UserContext.Provider
. It will have a value if I specify one when creating the context but not when I set it through the provider.
What am I doing wrong here?
CodePudding user response:
Your Auth
is called within the component but you call useContext
before Auth
usage which means your Context API has not been initialized yet
In the usual components, you can initialize them with a component wrapper like
<Context.Provider>
<YourComponent/> // you call `useContext` in `YourComponent`
</Context.Provider>
But in Next.js, especially, under a page-level component, it's not a good way to construct multiple Context APIs due to clean code concerns
I'd suggest you should move your Auth
to _app.tsx
like below that would help you initialize your Context API before all page-level components' renderings
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
CodePudding user response:
You cannot useContext
outside its Provider
.
You will need to move your Auth
component up a level so that it surrounds Dash
in order to make use of const contextMsg = useContext(UserContext)
In the end your React Component Tree should look like this:
<Auth>
<Dash />
</Auth>