Поскольку вы обновляете состояние внутри 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);
--- СЛЕДУЮЩИЙ ВОПРОС-- -
Я понимаю, что вы хотите создать метод для pu sh новых потомков потомков, указанных в id .
Я разработал метод, который поддерживает атрибуты и старые дочерние элементы:
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
для поддержки старых детей
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);