Reputation: 548
Instead of passing props
from parent to child1(parent of child2) ->to child2,
I want to use createContext
and receive the value with useContext
.
What I tried to do is not correct because and I'm getting an error **'booleanContext' is not defined
**.
How can I pass the createContext
state/value ?
App.js
CreatePass is a component inside SignUp
const [signUpFirst, setIfSignUp] = useState(true);
const booleanContext = createContext(setIfSignUp);
return (
<booleanContext.Provider value={setIfSignUp}>
<div>
</Switch>
<Route exact path='/signup'>
<SignUp homePage={exitSignUpPage} setUserNumber={setUserID} />
</Route>
<Route exact path='/home'>
<Home userIDNumber={userID} setIfSignUp={setIfSignUp} />
</Route>
<CreatPass />
</Switch>
</div>
</booleanContext.Provider>
);
SignUp.js
render() {
return (
<div className='signUp-div'>
<Header />
<Router history={history}>
<div className='form-div'>
<Redirect to='/signup/mobile' />
<Switch>
<Route exact path='/signup/mobile' component={MobileNum} />
<Route exact path='/signup/idnumber'>
<IdentNumber setPersonalID={this.props.setUserNumber} />
</Route>
<Route exact path='/signup/password'>
<CreatePass />
</Route>
</Switch>
</div>
</Router>
</div>
);
}
CreatePass.js //'booleanContext' is not defined no-undef
const CreatePass = () => {
const changeBooleanValue = useContext(booleanContext);
const handleClickButton = () => {
changeBooleanValue(true);
};
return (
<div className='form-div'>
<button onClick={handleClickButton}>Click</button>
</div>
);
};
export default CreatePass;
This solution is not good it's the same value as I did above, booleanContext
is undefined -
export const booleanContext = createContext(); // default value is undefiend
...
const App = () =>
return(
<booleanContext.Provider value={setIfSignUp}>
<CreatPass />
</booleanContext.Provider>
)
}
export default App;
Will be glad for explanations
Upvotes: 0
Views: 1546
Reputation: 422
Code looks ok. You can fix the default value error when exporting the context with an empty object {}
.
export const booleanContext = createContext({});
export default function App() {
...
return (
<booleanContext.Provider value={setIfSignUp}>
...
</booleanContext.Provider>
)
}
and import it CreatePass.js
import React, { useContext } from "react";
import { booleanContext } from "./App";
const CreatePass = () => {
const changeBooleanValue = useContext(booleanContext);
...
}
Upvotes: 0
Reputation: 476
for context provider and consumer, usually I create 1 hook for it like useBoolean.tsx
that return BooleanProvider
component that you can put inside your parent and useBoolean
function that you can import inside your child component.
Basically any global function should wrap all its children inside its Provider
.
So, if you want <CreatePass/>
to access the value from the provider, it needs to be a children of its Provider
<BooleanProvider>
<CreatePass/>
</BooleanProvider>
useBoolean.tsx
will have something like this
// useBoolean.tsx
const BooleanContext = createContext()
export const BooleanProvider = ({ children }) => {
const [signUpFirst, setIfSignUp] = useState(true)
return (
<BooleanContext.Provider value={{ signUpFirst, setIfSignUp }}>
{children}
</BooleanContext.Provider>
)
}
export const useBoolean = () => {
const context = useContext(BooleanContext)
if (context === undefined) {
throw new Error(`${useBoolean.name} must be within ${BooleanProvider.name}`)
}
return context
}
Parent component will be like usual
// Parent component
import { BooleanProvider } from 'hooks/useBoolean'
const Parent = () => (
<BooleanProvider>
<Child1 />
</BooleanProvider>
)
Child1 will have Child2 and Child2 will use the useBoolean function we created
// Child1 component
const Child1 = () => (
<div>
<Child2 />
</div>
)
// Child2 component
import { useBoolean } from 'hooks/useBoolean'
const Child2 = () => {
const { setIfSignUp } = useBoolean()
return <div></div>
}
Hope this helps clarify something for you. I am just trying to explain my understanding here on using the react context api and my way of doing it as well.
I tried to create hooks function like this for easier code management - it helps me understand what this context does directly with hooks naming convention. The hook function throws error too when it is not being used inside the Provider
:D. Cheers 🙏!
Upvotes: 6
Reputation: 617
Move "const booleanContext = createContext(setIfSignUp);" Outside of the component, you dont want to change context reference every render. Also export it for other components.
export const booleanContext = createContext(); // default value is undefiend
...
const App = () => ...
export default App;
Then in CreatePass, you should import context (used named export, so import would be like this:
import { booleanContext } from '..somePath../App'
Now it should work.
Works as expected https://codesandbox.io/s/createcontexttest-0qvvm?file=/src/App.js
<App>
<CreatePass /> // there is value undefined
<Context.Provider value={'something'}>
<CreatePass /> // value is defined
<SignUp>
<CreatePass /> // also defined
</SignUp>
</Context.Provider>
<div>
<CreatePass /> // undefined
</div>
</App>
Upvotes: 1
Reputation: 2171
first, create a custom component for your context provider:
import { createContext } from "react";
const CustomContext = createContext(["green", () => {}]);
export default CustomContext;
then wrap all your components using it in for example App.js:
<CustomContext.Provider value={options}>
[…]
</CustomContext.Provider>
and then you can use it as follows:
import CustomContext from "./CustomContext";
// top of SearchParams function body
const [options] = useContext(CustomContext);
Upvotes: -1