搜索

首页  >  问答  >  正文

ReactJS - 自定义挂钩返回函数不存储内部状态的实际数据

我有一个用于通知小部件的自定义挂钩useNotifications。这个钩子返回一个包含下一个元素的数组(它类似于 ant.design 消息 api):

当用户调用add时,他们会获得一个可用于删除通知的ID

该问题专门针对删除功能。由于我在添加新通知后立即调用此函数,因此该函数会收到旧列表的副本,因此没有新元素,并且会引发错误。我该如何修复它,以便组件使用相同的 API?

useNotification 钩子 我如何使用它

Codesandbox(为了测试,我做了setTimeout,它在3秒内调用了remove()):https://codesandbox.io/s/goofy-smoke-5q7dw3?文件=/src/App.js:405-440

P粉729436537P粉729436537448 天前479

全部回复(1)我来回复

  • P粉478188786

    P粉4781887862023-09-13 00:58:59

    您可以使您的 remove 函数使用 状态更新器功能,可以访问最新的状态值。这允许您在组件在 remove() 中重新渲染之前访问新的 list 状态。

    注意:您当前正在通过将嵌套对象的 isMounted 属性设置为 false 来改变原始状态。即使您复制了数组,您也应该复制正在更新的对象,以避免重新渲染问题。

    以下是有关如何访问状态的最新值并避免状态突变的一些修改:

    const add = useCallback((params) => {
      const id = v4();
      const element = {...params, id, isMounted: true};
      setList(list => [...list, element]); // Add your new element while also making a copy of the current state (`list`)
      return id;
    }, []);
    
    const remove = useCallback((elementId) => {
      setList((list) =>
        list.map((elem) => elem.id === elementId 
          ? { ...elem, isMounted: false } 
          : elem
        )
      );
      setTimeout(() => {
        setList((list) => list.filter((elem) => elem.id !== elementId));
      }, 500);
    }, []);
    

    参见下面的示例:

    回复
    0
  • 取消回复