Reactjs钩子中的递归函数?
我想使用react HooksReactjs钩子中的递归函数?,reactjs,react-hooks,Reactjs,React Hooks,我想使用react HooksuseState()更新状态 以下是一个例子: 我在应用程序顶部有全局状态: const [familyTree, setFamilyTree] = useState([ { fam_id: 1, name: "No name", attributes: { "Key1": "*", "Key2": "*", }, children: [ {
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()中的状态
也许你应该使用。映射并更新状态,然后在检查数组的末尾
这就是解决方案:
const matchAndUpdate=(更新程序,子项)=>{
返回children.map(_child=>{
if(updater.fam\u id===\u child.fam\u id){
返回{
…更新程序,
children:_child.children&&Array.isArray(_child.children)?matchAndUpdate(更新程序,_child.children):null
};
}否则{
返回{…\u child,children:\u child.children&&Array.isArray(\u child.children)?matchAndUpdate(更新程序,\u child.children):null};
}
});
};
这将返回和子数组,因此您将从初始数组开始:
const finalFamily=matchAndUpdate({fam_id:1,name:“name”},familyTree);
finalFamily
将是最终更新的数组
您可以按如下方式更新状态:
//选项1:
setFamilyTree(matchAndUpdate({fam_id:1,name:“name”},familyTree);
//备选案文2:
const newFamilyTree=matchAndUpdate({fam_id:1,name:“name”},familyTree);
setFamilyTree(新家族);
---下一个问题---
我知道您想创建一个方法,将新的子对象推送到id指定的子对象
我开发了一种方法来维护属性和老孩子:
const addChildrenToChild=(父,子)=>{
const arrayChildren=[];
for(设i=0;i
并升级match和update
,以维护年迈的孩子
const matchAndUpdate=(更新程序,子项)=>{
返回children.map(_child=>{
if(updater.fam\u id===\u child.fam\u id){
返回{
…更新程序,
children:updater.children
//过滤器更新程序子项
.filter(_childFiltered=>
_child.children&&Array.isArray(\u child.children)?
//检查旧的子项中是否存在新的子项
_孩子,孩子,一些(
_childToCheck=>\u childToCheck.fam\u id!=\u childToCheck.fam\u id
):对
)
//连接旧的子项并检查以更新
康卡特先生(
_child.children&&Array.isArray(_child.children)
?匹配和更新(更新程序,_child.children)
: []
)
};
}否则{
返回{
我的孩子,
儿童:
_child.children&&Array.isArray(_child.children)
?匹配和更新(更新程序,_child.children)
: []
};
}
});
};
现在,您可以同时使用其他方法添加新的子项:
//现在我们将向familyTree数组中的第一个元素添加新的子元素,并维护旧的子元素(如果有)。
const newFamilyTree=匹配和更新(
addChildrenToChild(familyTree[0],10),
家谱
);
setFamilyTree(newFamilyTree);
看起来您正在将族谱树设置为一个对象,而该对象不具有forEach
功能。您是否正在尝试将其设置为数组?看起来您正在将其初始化为数组。您好,您有什么建议吗?这只是我的尝试…谢谢兄弟!:)如果您有时间回答一个问题,请在这里回答我:)我有一个系统可以从for循环和push方法添加新的子项:这是一个事后思考,如何再次正确填写状态。。。我试图调用一个set方法和{…oldState,newState(使用循环和推送数组)}结果我得到了子对象,但父对象消失了…我会将其添加到应答器上。您应该使用其他类型的id,因为它们中的一个可能具有相同的值,并且未能通过先前的void解释的matchAndUpdate。您也可以添加随机字母