ReactJS - 自定义挂钩返回函数不存储内部状态的实际数据
P粉729436537
P粉729436537 2023-09-12 08:49:22
0
1
474

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

  • add:添加新通知的函数
  • remove:获取通知 ID 并删除通知的函数
  • contextHandler:传递到组件渲染的 JSX

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

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

useNotification 钩子 我如何使用它

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

P粉729436537
P粉729436537

全部回复(1)
P粉478188786

您可以使您的 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);
}, []);

参见下面的示例:

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板