我想使用 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/