reactjs - 使用 prevState 和 useState 钩子(Hook)更新对象内数组内的对象

标签 reactjs json react-hooks use-state

我想根据 id 等于传递的 prop 来删除嵌套对象。此刻,整个对象被替换。当尝试使用 useState 更新状态时,我可能遗漏了一些东西,可能是我循环对象的方式?

更新:该问题已针对可用的 answers 关闭用于更新嵌套对象。这个问题涉及数组,我认为这是当前问题的一部分。请注意此问题与 forEach 本质上的区别。也许需要一个 return 语句,或者使用不同的方法来过滤 id..

我的初始对象如下所示:

{
  "some_id1": [
    {
      "id": 93979,
      // MORE STUFF
   
    },
    {
      "id": 93978,
      // MORE STUFF
    }
  ],
  "some_id2": [
    {
      "id": 93961,
      // MORE STUFF
    },
    {
      "id": 93960,
      // MORE STUFF
    }
  ]
}

我会这样浏览每个项目:

for (const key in items) {
        if (Object.hasOwnProperty.call(items, key)) {
            const element = items[key];
            element.forEach(x => {
                if (x.id === singleItem.id) {
                    setItems(prevState => ({
                        ...prevState,
                        [key]: {
                            ...prevState[key],
                            [x.id]: undefined
                        }
                    }))
                }
            })
        }

最佳答案

您的代码中有 3 个问题:

  1. 您将 key 的值设置为一个对象,而 items 预计具有一个 ids 数组。
// current
[key]: {
 ...prevState[key],
 [x.id]: undefined
}

// expected
[key]: prevState[key].filter(item => item.id === matchingId)
  • 如果您打算根据某些条件从数组中删除对象,则应该使用 filter,如 Owen 的 answer 中指出的那样。因为你正在做的事情是别的事情:
  • const a = { xyz: 123, xyz: undefined };
    console.log(a); // { xyz: undefined} - it did not remove the key
    
  • 为了使代码更具可读性,需要操作整个对象 items,然后使用 setItems 将其设置为状态 - 相比之下根据某些条件在循环内多次调用 setItems

    这使您的代码更具可预测性并减少重新渲染。

  • 另外,您的问题的解决方案:

    // Define this somewhere
    const INITIAL_STATE = {
      "some_id1": [
        {
          "id": 93979
        },
        {
          "id": 93978
        }
      ],
      "some_id2": [
        {
          "id": 93961
        },
        {
          "id": 93960
        }
      ]
    };
    
    // State initialization
    const [items, setItems] = React.useState(INITIAL_STATE);
    
    // Handler to remove the nested object with matching `id`
    const removeByNestedId = (id, items) => {
      const keys = Object.keys(items);
      const updatedItems = keys.reduce((result, key) => {
        const values = items[key];
        // Since, we want to remove the object with matching id, we filter out the ones for which the id did not match. This way, the new values will not include the object with id as `id` argument passed.
        result[key] = values.filter(nestedItem => nestedItem.id !== id)
        return result;
      }, {});
      setItems(updatedItems);
    }
    
    // Usage
    removeByNestedId(93961, items);
    

    关于reactjs - 使用 prevState 和 useState 钩子(Hook)更新对象内数组内的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68642687/

    相关文章:

    javascript - 链接到 Next.js 中的动态路由

    java - 由 : java. lang.IllegalStateException 引起:应为字符串但为 BEGIN_OBJECT

    Beego Controller 中的 JSON 响应

    javascript - Next.js 上下文提供程序用页面特定布局组件包装 App 组件,提供未定义的数据

    javascript - react 原生 Typescript 路径别名无法解析模块

    javascript - 为什么使用 React Hooks、MomentJS 对象和间隔/超时更新状态不会触发重新渲染?

    css - 如何在用户滚动查看时设置动画

    javascript - Json 到 Jquery 数据表

    reactjs - 如何使用详尽的 deps lint 规则来安装/卸载效果

    reactjs - 使用回调声明的顺序