I am trying the new hooks features and stuck upon my state not being updated.
Actually the state is updated ( I can see the updated values in the console.log and my component reruns the useEffect) but the useEffect method uses my old state and save the signature to only the first user while The active user did change in the state.
I thought about adding useCallback and to move my methods to the useEffect or the component itself but I could manage to get it to work.
state:
const inititalState = {
displayHolder: true,
activeUser: 0,
signatureDate: new Date().toLocaleDateString('he'),
};
this is my useEffect:
useEffect(() => {
try {
...
canvas._canvas.addEventListener('mousedown', throttle(() => handleSignatureStart(dispatch), 500));
canvas._canvas.addEventListener(
'mouseup',
throttle(() => handleSignatureEnd(activatedUser, name, canvas, onFinish), 500),
);
...
// set to new signature and date
if (signature && typeof signature === 'string') {
dispatch({ type: 'setSignatureDetails', payload: { displayHolder: false, signatureDate } });
canvas.fromDataURL(signature);
} else {
dispatch({
type: 'clearSignatureDetails',
payload: { displayHolder: true, signatureDate: new Date().toLocaleDateString('he') },
});
}
//umount
return () => {
if (canvas) {
canvas._canvas.removeEventListener('mousedown', handleSignatureStart);
canvas._canvas.removeEventListener('mouseup', handleSignatureEnd);
}
};
} catch (error) {
console.error(error);
}
}, [dispatch]);
here is my reducer:
const signatureReducer = (state, { type, payload }) => {
console.log('@@@@', type, '@@@');
switch (type) {
case 'setSignatureDetails': {
const { displayHolder, signatureDate, activeUser } = payload;
const activeUserReady = activeUser === 0 || activeUser ? activeUser : state.activeUser;
console.log(activeUser, activeUserReady);
return { ...state, displayHolder, signatureDate, activeUser: activeUserReady };
}
case 'clearSignatureDetails': {
const { displayHolder, signatureDate } = payload;
return { ...state, displayHolder, signatureDate };
}
case 'hidePlaceholder': {
const { displayHolder } = payload;
return { ...state, displayHolder };
}
case 'showPlaceholder': {
const { displayHolder, activeUser } = payload;
const activeUserReady = activeUser === 0 || activeUser ? activeUser : state.activeUser;
console.log(activeUser, activeUserReady);
return { ...state, displayHolder, activeUser: activeUserReady };
}
default:
return state;
}
};
parent state:
users: [
{
name: 'foo',
forwhom: 0,
signatures: {
clientSignature: {
value: ''
}
}
},
{
name: 'bar',
forwhom: 1,
signatures: {
clientSignature: {
value: ''
}
}
}
]
Here is that part of my project which possibly demonstrates my issue. https://stackblitz.com/edit/react-51j5i6
Thanks
useEffect
, or it will not re-run with the correct values. - TholleuseEffect
leveragesstate
andprops
, but does not have them in the dependencies array. It is also very confusing to see the state and props being deconstructed both outside and inside useEffect with the same variable names. - Ryan Cogswell