I have 2 component, and a context provider, when I call my hook at parent level, I have no issue changing the state and having those 2 component getting the value via context
working demo of contex api usage but I call change state at parent level which is not what I wanted https://stackblitz.com/edit/react-51e2ky?file=index.js
I want to change state at inner component with hook, but I don't see the value been changed when I click on the navbar login
.
https://stackblitz.com/edit/react-rgenmi?file=Navbar.js
parent:
const App = () => {
const {user} = loginHook()
return (
<UserContext.Provider value={user}>
<Navbar />
<Content />
</UserContext.Provider>
);
}
Navbar.js
const Navbar = () => {
const user = React.useContext(userContex)
const {setUser} = loginHook()
return <div>{user ? <span>{user.name}</span> : <button onClick={() => {
setUser({
name: 'jane'
})
}}>navbar Login</button>}</div>
}
custom hook
const loginHook = () => {
const [user, setUser] = React.useState(null)
return {
user,
setUser
}
}
I can pass setUser from parent to children but I want to avoid that, I expect I can use context api and react hook seamlessly.
Currently, you're only setting the user
value in the context, which is why getting the correct value will work.
However, in your Navbar.js
component, you are making a call to loginHook
, which will create a new "instance" of that hook, effectively having its own state.
I suggest you add the update function in your context as well, as such
const App = () => {
const {user, setUser} = loginHook()
return (
<UserContext.Provider value={{ user, setUser}}>
<Navbar />
<Content />
</UserContext.Provider>
);
}
That way you can access the setUser
in your children as well, e.g.
const Navbar = () => {
const {user, setUser} = React.useContext(userContex)
return <div>{user ? <span>{user.name}</span> : <button onClick={() => {
setUser({
name: 'jane'
})
}}>navbar Login</button>}</div>
}
Also, small note: it's best to start you custom hook with use
, as that's a best-practice when writing your own hooks.
Important caveat however, this is not really a good practice. If your user
were to change, all components that are only listening to setUser
will also get an update an thus do a useless rerender. You can solve this by using two different contexts, one for the value, and one for the updater. You can read more about this here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With