React useState hook event handler using initial state
You have access to current state from setter function, so you could make it:
const handleResize = () => {
setActivePoint(activePoint => {
console.log(activePoint);
return activePoint;
})
};
How to Fix a Stale useState
Currently, your issue is that you're reading a value from the past. When you define handleResize
it belongs to that render, therefore, when you rerender, nothing happens to the event listener so it still reads the old value from its render.
There are a several ways to solve this. First let's look at the most simple solution.
Create your function in scope
Your event listener for the mouse down event passes the point
value to your resizerMouseDown
function. That value is the same value that you set your activePoint
to, so you can move the definition of your handleResize
function into resizerMouseDown
and console.log(point)
. Because this solution is so simple, it cannot account for situations where you need to access your state outside of resizerMouseDown
in another context.
See the in-scope function solution live on CodeSandbox.
useRef
to read a future value
A more versatile solution would be to create a useRef
that you update whenever activePoint
changes so that you can read the current value from any stale context.
const [activePoint, _setActivePoint] = React.useState(null);
// Create a ref
const activePointRef = React.useRef(activePoint);
// And create our custom function in place of the original setActivePoint
function setActivePoint(point) {
activePointRef.current = point; // Updates the ref
_setActivePoint(point);
}
function handleResize() {
// Now you'll have access to the up-to-date activePoint when you read from activePointRef.current in a stale context
console.log(activePointRef.current);
}
function resizerMouseDown(event, point) {
/* Truncated */
}
See the useRef
solution live on CodeSandbox.
Addendum
It should be noted that these are not the only ways to solve this problem, but these are my preferred methods because the logic is more clear to me despite some of the solutions being longer than other solutions offered. Please use whichever solution you and your team best understand and find to best meet your specific needs; don't forget to document what your code does though.