首页 > 解决方案 > Reactjs 使用 useReducer 更新对象数组中的嵌套数组

问题描述

我遇到了一些麻烦,我想我一定犯了一个我看不到的愚蠢错误。我正在尝试在我的 useReducer reducer 函数中创建一个函数,它将 todo.complete 值更新为 true 或 false(单击复选框时调用)。结构是 [Object].[todoList].complete: 默认为 false,但我想将其更改为 !complete。

我的减速器函数中的代码是......

       case "UPDATE_TODO_COMPLETE":
           let updatedTask = tasksState.filtered.filter((task) => {
                if (task.id === action.payload.task.id) {
                    return {
                        ...task,
                        todoList: task.todoList.map((todo) => {
                            if (todo.id === action.payload.todo.id) {
                                alert(todo.name);
                                return { ...todo, complete: !todo.complete };
                            }
                        }),
                    };
                }
            });

            tasksAPI_POST_Task_Update(updatedTask);

            return tasksState; //change to return updated object array when above is working

tasksAPI_POST_Task_Update(updatedTask); 最终会将更新发布到 API,但目前它只执行 console.log()。调用上述函数时,对象是日志回不具有更新的完整值。

我希望能够从对象数组中更新对象中的 todoList.todo。数组中的对象如下所示:

{
        name: "Bob's daily task",
        id: "1",
        bucketId: "1",
        setDate: "Mon May 24 2021 19:29:39 GMT+1200 (New Zealand Standard Time)",
        dueDate: "Tue May 25 2021 19:29:39 GMT+1200 (New Zealand Standard Time)",
        description:
            "This is a daily task which tells Bob what is needed to be done by todays EOB",
        status: 3,
        progress: 90,
        adminUsers: [
            {
                name: "Tom",
                id: "65e76cbe-07df-4c82-b94c-1e939cd3e6e5",
            },
        ],
        readOnlyUsers: [
            {
                name: "Roy",
                id: "idforroy",
            },
            {
                name: "Jack",
                id: "idforjack",
            },
        ],
        progressReports: [
            {
                id: "45987asdf87sd21sdf",
                name: "Report 1",
                date: "Mon May 24 2021 19:29:39 GMT+1200 (New Zealand Standard Time)",
                user: {
                    name: "Greg",
                    id: "65e76cbe-07df-4c82-b94c-1e939cd3e6e5",
                },
                report: "There was a big stuff up and now everything is a total mess!",
            },
        ],
        todoList: [
            {
                name: "todo1",
                id: "td1",
                complete: false,
                desription:
                    "This is the first todo. It requires doing a thing, about a thing, to fix another thing, cause that thing is broken",
            },
            {
                name: "todo2",
                id: "td",
                complete: false,
                desription:
                    "This todo is complementary to the first todo. Both of these must be completed to consider the task finished",
            },
        ],
    },

对此的任何帮助将不胜感激。我在这里错过了什么吗?还是有更简单的方法来做到这一点?

编辑:这对 API 调用函数很有意义。我想要将它包含在减速器中的唯一原因是因为这个减速器在我的应用程序中的多个组件上使用,所以我希望我能够从减速器中调用它。reducer 的初始状态是一个任务列表。这个列表有两个版本,tasksState,它是从 API 中获取的,以及过滤后的,它是在应用程序中实际显示的。我有一个单独的数据过滤版本,因为有排序和搜索功能,它需要 tasksState 生成过滤后显示。tasksState 由许多上述对象组成。查看特定任务时,有一个待办事项列表,我要更新的是单个 todo.complete。虽然这似乎适用于:

return {
                ...tasksState,
                filtered: tasksState.filtered.map((task) => {
                    if (task.id === action.payload.task.id) {
                        return {
                            ...task,
                            todoList: task.todoList.map((todo) => {
                                if (todo.id === action.payload.todo.id) {
                                    return { ...todo, complete: !todo.complete };
                                } else {
                                    return todo;
                                }
                            }),
                        };
                    } else {
                        return task;
                    }
                }),
                tasksState: tasksState.tasksState.map((task) => {
                    if (task.id === action.payload.task.id) {
                        return {
                            ...task,
                            todoList: task.todoList.map((todo) => {
                                if (todo.id === action.payload.todo.id) {
                                    return { ...todo, complete: !todo.complete };
                                } else {
                                    return todo;
                                }
                            }),
                        };
                    } else {
                        return task;
                    }
                }),
            };

谢谢,

格雷格

标签: javascriptarraysreactjsobjectuse-reducer

解决方案


推荐阅读