Reputation: 81
I face an issue when using useCallback hook of react. When I use normal arrow functions, It calls the setSlimSideBar(!slimSideBar) but useCallback doesn't call or not setting value as expected.
const [slimSideBar, setSlimSideBar] = useState(true)
This set state as Expected.
const toggle = () => {
console.log(slimSideBar)
console.log(!slimSideBar)
setSlimSideBar(!slimSideBar)
}
The below function doesn't set the state as I expected.
const toggle = React.useCallback(() => {
console.log(slimSideBar)
console.log(!slimSideBar)
setSlimSideBar(!slimSideBar)
},[setSlimSideBar])
Any Ideas why useCallback doesn't call setSlimBar function?
Upvotes: 1
Views: 1772
Reputation: 370709
What useCallback
does is, it will return the new function passed into it if any of the items in its dependency array have changed (are ===
, essentially) since last render. State setters are stable references; your setSlimSideBar
will refer to exactly the same function over the whole life of the component. As a result:
const toggle = React.useCallback(() => {
// ...
},[setSlimSideBar])
Because the only item in the dependency array never changes, the function returned by useCallback
never changes.
Add slimSideBar
to the dependency array so that when it changes, the returned function changes as well.
const toggle = React.useCallback(() => {
// ...
},[slimSideBar, setSlimSideBar]);
Or use the callback form of the state setter, so you don't have to rely on the outer state variable being up-to-date.
const toggle = React.useCallback(() => {
setSlimSideBar(slimSideBar => !slimSideBar);
},[setSlimSideBar]);
Upvotes: 3