React Redux Toolkit中addProgress逻辑求助:待办任务无法移至进行中
Redux Toolkit Todo迁移至InProgress功能修复方案
我在实践Redux Toolkit时遇到问题:待办任务(Todo)迁移至进行中(InProgress)模块的功能失效,addTodo功能正常,但addProgress无法工作。核心错误是当前addProgress逻辑在progress的state中查找对应id的任务,正确逻辑应该是从todos的state中获取该任务,添加至progress并从todos中移除。
1. 为todosSlice添加移除任务的Reducer
在todosSlice.js中新增removeTodo reducer,用于移除被迁移的任务:
import { createSlice } from "@reduxjs/toolkit"; const todosSlice = createSlice({ name: "todos", initialState: [], reducers: { addTodo: (state, action) => { // 替换固定id为动态生成的唯一值,避免重复 state.push({ id: Date.now(), text: action.payload, }); }, toggleTodo: (state, action) => { const todo = state.find((todo) => todo.id === action.payload); if (todo) { todo.completed = !todo.completed; } }, // 新增移除任务的reducer removeTodo: (state, action) => { return state.filter(todo => todo.id !== action.payload); } }, }); export const { addTodo, toggleTodo, removeTodo } = todosSlice.actions; export default todosSlice.reducer;
2. 修改progressSlice,使用createAsyncThunk处理跨slice操作
单个slice的reducer无法直接访问其他slice的state,因此用createAsyncThunk处理跨slice的任务迁移逻辑:
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; import { removeTodo } from "../todo/todosSlice"; // 创建异步thunk,处理任务迁移 export const addProgress = createAsyncThunk( "progress/addProgress", async (todoId, { getState, dispatch }) => { // 从全局state中获取todos列表 const { todos } = getState(); const targetTodo = todos.find(todo => todo.id === todoId); if (targetTodo) { // 先移除todos中的目标任务 dispatch(removeTodo(todoId)); // 返回任务数据用于添加到progress return targetTodo; } return null; } ); const progressSlice = createSlice({ name: "progress", initialState: [], reducers: {}, // 通过extraReducers处理thunk的执行结果 extraReducers: (builder) => { builder .addCase(addProgress.fulfilled, (state, action) => { if (action.payload) { // 将任务添加到progress列表 state.push(action.payload); } }); } }); export default progressSlice.reducer;
3. 组件调用保持不变
Todo组件中的按钮逻辑无需修改,确保正确引入新的addProgress即可:
import { addProgress } from '../features/inProgress/inProgressSlice'; // 按钮部分 <button onClick={() => { dispatch(addProgress(todo.id)) }} > 移至进行中 </button>
4. 优化InProgress组件
保留核心渲染逻辑,移除不必要的加载判断:
import React from "react"; import { useSelector } from "react-redux"; const InProgress = () => { const progress = useSelector((state) => state.progress); return ( <div> <div> <h2>In Progress</h2> <ul> {progress.map((item) => ( <li key={item.id}>{item.text}</li> ))} </ul> </div> </div> ); }; export default InProgress;
额外注意事项
- 原
todosSlice中addTodo的固定id(111)会导致所有任务id重复,必须替换为动态生成的唯一值(如Date.now()或uuid库),否则会引发任务查找错误。 - Redux Toolkit内置Immer库,支持在reducer中直接修改state或返回新state,两种写法均有效。
内容的提问来源于stack exchange,提问作者Varun Savai
相关产品推荐
相关产品推荐

