React hooks状态未更新

问题描述 投票:0回答:1

我正在尝试新的钩子功能,并坚持我的状态没有更新。

实际上状态已更新(我可以看到console.log中的更新值,我的组件重新运行useEffect)但useEffect方法使用我的旧状态并将签名保存到第一个用户而活动用户确实在状态中更改。

我考虑添加useCallback并将我的方法移动到useEffect或组件本身,但我可以设法让它工作。

州:

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

这是我的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]);

这是我的减速机:

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;
    }
};

父州:

  users: [
    {
      name: 'foo',
      forwhom: 0,
      signatures: {
        clientSignature: {
          value: ''
        }
      }
    },
    {
      name: 'bar',
      forwhom: 1,
      signatures: {
        clientSignature: {
          value: ''
        }
      }
    }
  ]

这是我的项目的一部分,可能会说明我的问题。 https://stackblitz.com/edit/react-51j5i6

谢谢

reactjs react-hooks
1个回答
0
投票

从您的演示中很难看出您想要的状态。但是,根据我的理解,我相信你的useEffect依赖应该是这样的:

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

还有其他几件事;正如@Ryan Cogswell指出的那样,你不需要在useEffect回调中重新定义activeUser

另外,在你的useEffect回调中;如果您打算在更新活动用户(IE多次)时运行此函数,您应该删除事件侦听器或检查是否已添加侦听器以防止每次渲染添加事件侦听器。

© www.soinside.com 2019 - 2024. All rights reserved.