简体   繁体   English

反应挂钩状态未更新

[英]React hooks state isnt updated

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. 实际上状态是更新的(我可以在console.log中看到更新的值,并且我的组件重新运行useEffect),但是useEffect方法使用我的旧状态并将签名保存到仅第一个用户,而活动用户确实在状态中进行了更改。

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. 我考虑过添加useCallback并将我的方法移到useEffect或组件本身,但是我可以设法使其正常工作。

state: 州:

const inititalState = {
  displayHolder: true,
  activeUser: 0,
  signatureDate: new Date().toLocaleDateString('he'),
};

this is my useEffect: 这是我的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 https://stackblitz.com/edit/react-51j5i6

Thanks 谢谢

It's difficult to see what your desired state should be from your demo. 从演示中很难看到所需的状态。 But, from what I understand, I believe your useEffect dependencies should be like this: 但是,据我了解,我相信您的useEffect依赖项应如下所示:

useEffect(() => {
  ...
}, [activeUser]);

A couple other things; 其他几件事; as @Ryan Cogswell pointed out, you do not need to redefine activeUser inside the useEffect callback. 正如@Ryan Cogswell指出的那样,您不需要在useEffect回调中重新定义activeUser

Also, inside your useEffect callback; 另外,在useEffect回调内部; if you intend to run this function on update to the active user (IE multiple times), you should either remove the event listeners or check if the listeners have been added to prevent adding event listeners each render. 如果打算在更新活动用户时多次运行此功能(即IE),则应删除事件侦听器或检查是否已添加侦听器,以防止在每个渲染时添加事件侦听器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM