在 React 中使用多个嵌套 children 修改状态

Modify state with multiple nested children in React

我正在尝试构建一个像选择树一样工作的组件,但用户可以编辑选择树中的每一行。

基本上,一个组件,您可以在其中继续向下钻取以获取更多详细信息。

数据的结构类似于嵌套 object,其中具有向下钻取可能性的项目具有 children,如下所示。

  const [categories, setCategories] = useState([
    {
      name: "First Tier",
      identifier: "1",
      children: [
        {
          name: "Second Tier",
          identifier: "2",
          children: [
            {
              name: "Third Tier",
              identifier: "3",
              children: [
                {
                  name: "Fourth Tier",
                  identifier: "4",
                  children: [{ name: "Fifth Tier", identifier: "5" }],
                },
              ],
            },
          ],
        },
      ],
    },
    { name: "Another top tier", identifier: "6" },
    { name: "a Third top tier", identifier: "7" },
  ]);

我的挑战是我似乎无法找到一种方法来按照我的意愿修改 child 和道具。 例如,我希望能够将第五个 child 的名称修改为某个随机名称。注意 - 我希望能够修改任何内容 child,并且我将拥有可用的标识符。

因为我使用的是react,所以需要使用“useState”来完成,根据我的理解,这使得它有点棘手。

任何想法或任何人都经历过这个挑战?

下面介绍的是实现所需 objective.

的一种可能方法

代码段

const findAndUpdate = (id, val, arr) => {
  // find 'arr' element with matching identifier
  const tgtObj = arr.find(
    ({ identifier }) => identifier === id
  );
  if (tgtObj) {             // found identifier, so update the name
    tgtObj.name = val;      // this will mutate the original array passed as argument
  } else {                  // not found, recurse through 'children' array
    arr.filter(el => 'children' in el).forEach(
      ({ children }) => findAndUpdate(id, val, children)
    );
  };
  return arr;               // in all cases, return 'arr' as-is
};

const stateArr = [
    {
      name: "First Tier",
      identifier: "1",
      children: [
        {
          name: "Second Tier",
          identifier: "2",
          children: [
            {
              name: "Third Tier",
              identifier: "3",
              children: [
                {
                  name: "Fourth Tier",
                  identifier: "4",
                  children: [{ name: "Fifth Tier", identifier: "5" }],
                },
              ],
            },
          ],
        },
      ],
    },
    { name: "Another top tier", identifier: "6" },
    { name: "a Third top tier", identifier: "7" },
  ];

// the 'stateArr' will be mutated by using this method
console.log(
  'find id: 5 and update name: "New Fifth Tier"... ',
  findAndUpdate("5", "New Fifth Tier", stateArr)
);

// to call this using "setCategories", simply try this:
/*
setCategories(prev => findAndUpdate("5", "New Fifth Tier", prev));
*/
.as-console-wrapper { max-height: 100% !important; top: 0 }

说明

在上面的代码段中添加了内联评论。