当前位置: 首页 > 知识库问答 >
问题:

反应挂钩状态未更新

鲁城
2023-03-14

我正在尝试新的hooks功能,并坚持认为我的状态没有更新。

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

我想过添加useCallback,并将我的方法移动到use效果或组件本身,但我可以设法让它工作。

状态:

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

这是我的效果:

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

谢谢

共有1个答案

蒲昊
2023-03-14

很难从演示中看出你想要的状态应该是什么。但是,据我所知,我相信您的use效应依赖关系应该是这样的:

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

其他一些事情;正如@Ryan Cogswell指出的,您不需要在useEffect回调中重新定义activeUser

此外,在useEffect回调中;如果要在更新到活动用户时运行此函数(即多次),则应删除事件侦听器或检查是否已添加侦听器,以防止在每个渲染中添加事件侦听器。

 类似资料:
  • 我正在尝试使用状态将一个表单输入值复制到另一个表单输入值,但状态没有更新 我创建了一个带有按钮的表单,其中左侧表单输入的值应复制到右侧表单输入。这是我的代码: 无论我做什么,dbSecName的状态都不会改变。我试着设置一个新的常量。我尝试使onclick函数异步并等待。如果我为我试图设置的变量的值添加,我可以正确地看到它,但是dbSecName的console.log总是显示原始值。 我真的不知

  • 问题内容: 在这里,我尝试设置为’hello’,然后打印它,但是状态似乎为空。当我刚刚使用更新状态时怎么办?设置为全局变量。 问题答案: 从reactjs文档中: 不会立即变异,但会创建待处理的状态转换。调用此方法后进行访问可能会返回现有值。 https://facebook.github.io/react/docs/component- api.html 您可以做的是将状态更新后传递给回调函数:

  • 问题内容: 我正在尝试新的React Hooks,并有一个带有计数器的Clock组件,该计数器应该每秒增加一次。但是,该值不会增加到超过一。 问题答案: 原因是传递给的闭包中的回调仅访问第一个渲染器中的变量,而无法访问后续渲染器中的新值,因为第二次未调用。 回调中的值始终为0 。 就像您熟悉的状态挂钩一样,状态挂钩有两种形式:一种是处于更新状态的状态,另一种是将当前状态传入的回调形式。您应该使用第

  • 我正在试用新的反应挂钩,并有一个时钟组件,计数器应该每秒钟增加一次。但是,该值不增加超过1。

  • 在这个项目中,我使用了反应钩,这个片段用来改变项目的颜色主题,但有一个问题,我无法解决。常量lightTheme={...} Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eusmod tempor incidunt ut labore et dolore magna aliqua. 我的减速器:

  • 如何在功能组件中使用preState和use效果?我被告知要更新类组件到功能组件,我被困在了组件的didUpdate部分