在 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 }
说明
在上面的代码段中添加了内联评论。
我正在尝试构建一个像选择树一样工作的组件,但用户可以编辑选择树中的每一行。
基本上,一个组件,您可以在其中继续向下钻取以获取更多详细信息。
数据的结构类似于嵌套 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 }
说明
在上面的代码段中添加了内联评论。