javascript - 如何使用 useReducer 更新嵌套数组?
问题描述
我有这些:
export type DataItemChild = {
id: number;
title:string;
checked?: boolean;
};
请注意,子项可以在此处未定义:
export type DataItems = {
id: number;
title:string;
subItems?: Array<DataItemChild>;
checked?: boolean;
};
export const initalState: StateType = {
items: [],
date: new Date(),
};
到目前为止,我已经弄清楚如何更新顶级对象上的数组,例如:
case ActionKind.Checked:
newArrayChecked = state.items.map((item) => ({
...item,
checked: item.id === payload.id ? true : item.checked,
}));
return {
...state,
items: newArrayChecked,
};
我不知道如何更新子项?我有这个(精简)
export const reducer = (state: StateType, action: Action) => {
const { type, payload } = action;
let newArrayChildCheck: Array<DataItemChild> = []
switch (type) {
case ActionKind.UnCheckedSub:
newArrayChildCheck = state.items.map((item) => ({
...item.subItems?.map((sub, index) => ({
checked: sub.id === payload.subItems?[index].id ? true: sub.checked
})),
}));
return {
...state,
items.subItems: newArrayChildCheck,
};
default:
return state;
}
};
但这给了我一个打字错误,说我的 newArrayChildCheck 不支持未定义。完整错误:
键入'{ [x:数字]:{检查:布尔| 不明确的; }; 长度?:数字 | 不明确的; toString?: (() => 字符串) | 不明确的; toLocaleString?: (() => 字符串) | 不明确的; 流行?:(()=> {检查:布尔|未定义;}|未定义)| 不明确的; ... 29 更多 ...; [Symbol.unscopables]?: (() => { ...; }) | 不明确的; }[]' 不可分配给类型 'DataItemChild[]'。键入'{ [x:数字]:{检查:布尔| 不明确的; }; 长度?:数字 | 不明确的; toString?: (() => 字符串) | 不明确的; toLocaleString?: (() => 字符串) | 不明确的; 流行音乐?:(()=
编辑:
在@Kelvin Schoofs 回答之后,我意识到我正在发送一个包含子项的整个对象。有效载荷是一种类型DataItems
我根据@Kelvin Schoofs 的建议修改了我的尝试,稍作改动:
newArrayChildCheck = state.items.map((item) => ({
...item,
subItems: item.subItems?.map((sub, index) => ({
...sub,
checked: sub.id === payload.subItems[index].id ? true : sub.checked
})),
不是[index]
但我越来越
对象可能未定义
解决方案
似乎您错误地传播了新对象。您.map((item) => ...)
返回一个对象,但您在其中传播了一个(潜在的)数组,该数组只会填充数字(好吧,字符串化版本)键。您可能打算从 和 复制原始字段,item
并将映射结果分配给该字段。您在. 像这样的东西是类型正确的:id
title
subItems
subItems
subItems?.map
newArrayChildCheck = state.items.map((item) => ({
...item,
subItems: item.subItems?.map((sub) => ({
...sub,
checked: sub.id === payload.id ? true : sub.checked
})),
}));
那就是如果你想要你的DataItems
数组的一个改变版本。如果你真的想返回每一个更改DataItemChild
过的checked
版本,你可以flatMap
这样使用:
newArrayChildCheck = state.items.flatMap((item) =>
item.subItems?.map((sub) => ({
...sub,
checked: sub.id === payload.id ? true : sub.checked
})),
);
推荐阅读
- python - MySQLdb 是模块还是接口?
- react-native - 在 Android 上通过 React Native 中的模块发出事件
- python - 通过逗号和透视解析数据框列 - python
- javascript - 在 Angular 6 中访问嵌套数组
- jquery - 当鼠标悬停在一个图像上时,jquery 或 CSS 会使其余图像变暗
- c++ - 代码::块:无法打开文件:../libgcc/unwind-sjlj.c
- wordpress - 获取分类字段的祖先类别术语的 slug (Wordpress / ACF)
- php - PHP数组二维,如何检查2个值是否在里面以及它们的位置
- node.js - 不会使用 Visual Studio 代码更新 npm
- php - 请描述如何使用 Quickbooks PHP SDK 查询包含特定服务日期的行项目的 Quickbooks 发票