The basic case
function App() {
const [count, setCount] = useState(0);
const handleClick = () = > {
setCount(2);
func(); // Press to print 0
};
const func = () = > {
console.log(count);
};
return (
<div className="App">
<button onClick={handleClick}>Click on the</button>
</div>
);
}
Copy the code
When we click the button, the console prints the last value, 0, instead of the latest value, 2
In order to reduce the number of render times, React collects all state changes, compares the optimization, and finally makes a change. Func calls and setCount are in the same macro task as react. So if you just use count to get the value 0 from the last closure
Yes, this is a solution, but sometimes there is more than one state to be passed. Again, because of react-hooks, So I chose to implement custom hooks to get the latest values immediately after useState changes. Let’s look at the implementation. The code changes are as follows:
function App() {
const [count, setCount] = useState(0);
const handleClick = () = > {
setstate(2);
func(); / / print 2
};
/** Passes the func method to useSyncCallback and returns a new function */
const func = useSyncCallback(() = > {
console.log(count);
});
return (
<div className="App">
<button onClick={handleClick}>Click on the</button>
</div>
);
}
export default App;
Copy the code
How to implement useSyncCallback?
import { useEffect, useState, useCallback } from 'react';
const useSyncCallback = callback= > {
const [proxyState, setProxyState] = useState({ current: false });
const Func = useCallback(() = > {
setProxyState({ current: true });
}, [proxyState])
useEffect(() = > {
if (proxyState.current === true) setProxyState({ current: false });
}, [proxyState])
useEffect(() = > {
proxyState.current && callback();
})
return Func
}
export default useSyncCallback;
Copy the code