如何在Redux中更新嵌套数组内指定索引的对象状态?
Got it, let's break down how to update that specific subtask in your nested array structure while following Redux's immutability rules. Here's a step-by-step solution:
Step 1: Understand the Immutable Update Requirement
Redux requires you to never mutate the original state directly—you always need to create copies of the parts you want to modify. For nested arrays/objects, this means copying each level of the structure that changes.
Step 2: Implement the Reducer Logic
In your ON_CHECK_BOX_CLICK case, we'll iterate through your task array, find the matching subtask from action.payload, and update its state.
First, a quick note: To reliably match the subtask, it's best if each subtask has a unique identifier (like an id property). If you don't have one yet, you might use a combination of task_name and its parent maintask name (though this can cause issues if duplicates exist). For this example, I'll assume action.payload includes the subtask object we need to update, and we'll match using task_name (adjust this to use a unique ID if you add one later).
Here's the updated reducer code:
const INITIAL_STATE = { tasks: { taskArray: [ { maintask: 'Main task 1', subtask: [ { photo_urls: [], task_name: 'Task 1', task_status: false }, { photo_urls: [], task_name: 'Task 2', task_status: false } ] }, { maintask: 'Main task 2', subtask: [ { photo_urls: [], task_name: 'Task 1', task_status: false }, { photo_urls: [], task_name: 'Task 2', task_status: false } ] } ] } }; export default (state = INITIAL_STATE, action) => { switch (action.type) { case ON_CHECK_BOX_CLICK: // Extract the target subtask from action payload const targetSubtask = action.payload; // Create an updated version of the taskArray const updatedTaskArray = state.tasks.taskArray.map(maintask => { // Find the index of the target subtask in the current maintask's subtask array const subtaskIndex = maintask.subtask.findIndex(subtask => subtask.task_name === targetSubtask.task_name // Add more conditions here if needed (e.g., match parent maintask name) // && maintask.maintask === targetSubtask.parentMaintaskName ); // If we found the subtask, update it if (subtaskIndex !== -1) { // Create a copy of the subtask array const updatedSubtasks = [...maintask.subtask]; // Update the specific subtask (toggle task_status here, or set to a new value) updatedSubtasks[subtaskIndex] = { ...updatedSubtasks[subtaskIndex], task_status: !updatedSubtasks[subtaskIndex].task_status // Or if you're passing a new status via payload: task_status: action.payload.newStatus }; // Return a new maintask object with the updated subtasks return { ...maintask, subtask: updatedSubtasks }; } // If no match, return the original maintask return maintask; }); // Return the new state with updated tasks return { ...state, tasks: { ...state.tasks, taskArray: updatedTaskArray } }; default: return state; } };
Key Notes
- Immutability: We use spread operators (
...) to create copies of arrays and objects instead of modifying the original state. This ensures Redux can detect state changes correctly. - Matching Subtasks: Using
task_nameis a temporary fix—for production code, add a uniqueidto each subtask (e.g.,id: 'subtask-1-1'for the first subtask of the first main task) to avoid matching duplicate task names. - Flexibility: If you need to update other properties (like
photo_urls), just add them to the updated subtask object.
内容的提问来源于stack exchange,提问作者Shubham

