reactjs - Reactjs Hooks 中的递归函数?

标签 reactjs react-hooks

我想使用 React Hooks useState(); 更新状态?

这是一个例子:

我在应用程序顶部有全局状态:

const [familyTree, setFamilyTree] = useState([
    {
      fam_id: 1,
      name: "No name",
      attributes: {
        "Key1": "*",
        "Key2": "*",
      },
      children: [
        {
          fam_id: 2,
          name: "No Name2",
          attributes: {
            "Key1": "*",
            "Key2": "*",
          },
        },
      ],
    },
  ]);

我有一个当前对象来更新全局状态:

let res = {
          fam_id: 2,
          name: "No Name2",
          attributes: {
            "Key1": "Update this",
            "Key2": "*",
          },
        },

本例中的递归函数帮助我用匹配的 ID 更新全局状态,但我现在遇到了问题,

const matchAndUpdate = (updater, target) => {
      if (updater.fam_id === target.fam_id) {
        target.name = updater.name;
        target.attributes = updater.attributes;
      }

      if ("children" in target && Array.isArray(target.children)) {
        target.children.forEach((child) => {
          matchAndUpdate(updater, child);
        });
      }
    };
    familyTree.forEach((g) => {
      matchAndUpdate(res, g);
      setFamilyTree({ ...g }); // here is my try, this works on start, but on secound update i got error about forEach is not a function...
    });

我不知道在哪里以正确的方式更新状态

谢谢,o/

最佳答案

因为您更新了 forEach() 内部的状态。

也许您应该使用 .map 并在检查数组末尾更新状态。

这是解决方案:

const matchAndUpdate = (updater, children) => {
    return children.map(_child => {
      if (updater.fam_id === _child.fam_id) {
        return {
          ...updater,
          children: _child.children && Array.isArray(_child.children) ? matchAndUpdate(updater, _child.children) : null
        };
      } else {
        return {..._child,children: _child.children && Array.isArray(_child.children) ? matchAndUpdate(updater,_child.children) : null};
      }
    });
  };

这将返回子数组,因此您将从初始数组开始:

 const finalFamily = matchAndUpdate({ fam_id: 1, name: "Name" }, familyTree);

finalFamily 将是最终更新的数组。

您可以像这样更新状态:

// Option 1:
setFamilyTree(matchAndUpdate({ fam_id: 1, name: "Name" }, familyTree);

// Option 2:
const newFamilyTree = matchAndUpdate({ fam_id: 1, name: "Name" }, familyTree);
setFamilyTree(newFamily);

--- 下一个问题-- -

我知道您想要创建一个方法来将新子项推送到 id 指定的子项。

我开发了一种维护属性和老 child 的方法:

  const addChildrenToChild = (parent,numChildren) => {
    const arrayChildren = [];
    for (let i = 0; i < numChildren; i++) {

      arrayChildren.push({
        fam_id: Math.floor(Math.random() * 100),
        name: "No name",
        attributes: {
        key1:"",
        key2:""
        },

      });
    }

    return {...parent,children:parent.children && Array.isArray(parent.children) ? parent.children.concat(arrayChildren) : arrayChildren }
  }

并升级matchAndUpdate以维护老 child

 const matchAndUpdate = (updater, children) => {
    return children.map(_child => {
      if (updater.fam_id === _child.fam_id) {
        return {
          ...updater,
          children: updater.children
          //Filter updater children 
            .filter(_childFiltered =>
              _child.children && Array.isArray(_child.children) ? 
              //check if exists new child in old children
              _child.children.some(
                _childToCheck => _childToCheck.fam_id !== _childFiltered.fam_id
              ) : true
            ) 
            //concat old children and check to update
            .concat(
              _child.children && Array.isArray(_child.children)
                ? matchAndUpdate(updater, _child.children)
                : []
            )
        };
      } else {

        return {
          ..._child,
          children: 
              _child.children && Array.isArray(_child.children)
                ? matchAndUpdate(updater, _child.children)
                : []
        };
      }
    });
  };

现在。您可以同时使用其他方法来添加新的子项:

// Now we are going to add new children to the first element in familyTree array, and maintains old children if it has.
const newFamilyTree = matchAndUpdate(
    addChildrenToChild(familyTree[0], 10),
    familyTree
  );

setFamilyTree(newFamilyTree);

关于reactjs - Reactjs Hooks 中的递归函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61278206/

相关文章:

reactjs - 为什么从 React 的 useEffect 依赖列表中省略函数是不安全的?

reactjs - 从 React Native 中的自定义按钮更改状态

javascript - 当将函数传递给子 React 时,获取 this.props 不起作用

reactjs - React Linting,缺少 "react"的文件扩展名(导入/扩展)

javascript - 如何使用reactjs或nextjs中的下拉选项为数组创建动态常量名称?

javascript - 在组件重新渲染时重置滚动位置

javascript - 在 React JS 中更新状态

reactjs - react useState setter导致重新渲染

reactjs - 在 typescript 中将 useState 作为 props 传递

reactjs - React Hooks useCallback 和备忘录列表重新渲染