I have created the following context in React:
import { useBoolean } from "@chakra-ui/react"
import { createContext, FC } from "react"
type useBooleanReturn = ReturnType<typeof useBoolean>
export const MobileContext = createContext<
[show: useBooleanReturn[0], setShow: useBooleanReturn[1]] | undefined
>(undefined)
// --- PROVIDER
const MobileProvider: FC = ({ children }) => {
const [show, setShow] = useBoolean()
return (
<MobileContext.Provider value={[show, setShow]}>
{children}
</MobileContext.Provider>
)
}
export default MobileProvider
So far so good, but when I try and use this context it turns out that what is being passed down is undefined
. That is, in the following code value
is undefined:
const value = React.useContext(MobileContext)
I don't know why that is, though, since I use the useBoolean
hook when setting up the context -- i.e., this line: const [show, setShow] = useBoolean()
. I then pass on show
and setShow
to my context with this line: value={[show, setShow]}
. As such, shouldn't value be defined with an array with two values (namely show
and setShow
)?
Any idea why that is NOT happening and what can I do to fix it?
Thanks.
UPDATE
Here is the full example of when I call useContext
:
import * as React from "react"
import MobileProvider, { MobileContext } from "./context.mobile"
const Mobile = () => {
const value = React.useContext(MobileContext)
console.log("value:", value)
...
The above is what I did for testing purposes. Here is what I the code is actually supposed to look like:
import * as React from "react"
import Base from "./base"
import Header from "./Header"
import Menu from "./Menu"
import Footer from "./Footer"
import MobileProvider, { MobileContext } from "./context.mobile"
const Mobile = () => {
const [show, setShow] = React.useContext(MobileContext)
return (
<MobileProvider>
<Base onClick={setShow.toggle} ref={ref} show={show}>
<Header onClick={setShow.toggle} />
<Menu />
<Footer />
</Base>
</MobileProvider>
)
}
export default Mobile
You suppose to call useContext
on PROVIDER'S CONSUMERS.
In other words, the component which calls the useContext
(Mobile
) must be a child of MobileProvider
.
In your case, its not a consumer, thats not how the API defined, therefore you will get the default value (undefined
) since its called out of context.
const Mobile = () => {
// NOT A CONSUMER
const [show, setShow] = React.useContext(MobileContext)
return (
<MobileProvider>
...
</MobileProvider>
)
}
Move the component to MobileProvider
tree
<MobileProvider>
<Mobile/>
</MobileProvider>
const Mobile = () => {
// NOW A CONSUMER
const [show, setShow] = React.useContext(MobileContext)
return (
<Base onClick={setShow.toggle} ref={ref} show={show}>
...
</Base>
)
}