温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

React+Redux怎么实现简单的待办事项列表ToDoList

发布时间:2022-04-20 17:43:40 来源:亿速云 阅读:479 作者:iii 栏目:大数据
# React+Redux怎么实现简单的待办事项列表ToDoList ## 目录 - [前言](#前言) - [技术选型分析](#技术选型分析) - [项目初始化](#项目初始化) - [React组件设计](#react组件设计) - [Redux状态管理](#redux状态管理) - [功能实现详解](#功能实现详解) - [样式优化](#样式优化) - [项目扩展思路](#项目扩展思路) - [常见问题解决](#常见问题解决) - [总结](#总结) ## 前言 在现代Web开发中,React作为主流前端框架之一,配合Redux状态管理工具,能够高效构建复杂的交互界面。本文将通过实现一个功能完整的ToDoList应用,详细讲解以下核心知识点: 1. React函数组件与Hooks的使用 2. Redux Toolkit现代化状态管理 3. 组件间的数据传递与通信 4. 列表渲染与条件判断 5. 用户交互事件处理 最终实现的ToDoList将包含以下功能: - 添加新待办事项 - 标记事项完成状态 - 按状态筛选事项 - 删除事项 - 本地存储持久化 ## 技术选型分析 ### 为什么选择React+Redux组合? **React优势**: - 组件化开发模式 - 虚拟DOM高效渲染 - 丰富的生态系统 - 单向数据流易于理解 **Redux优势**: - 集中式状态管理 - 可预测的状态更新 - 方便的状态调试 - 中间件扩展机制 ### 技术栈版本 ```json "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "@reduxjs/toolkit": "^1.9.5", "react-redux": "^8.1.2" } 

项目初始化

1. 创建React项目

npx create-react-app todo-list-redux --template typescript cd todo-list-redux npm install @reduxjs/toolkit react-redux 

2. 项目结构设计

/src /components TodoItem.tsx TodoList.tsx AddTodo.tsx Filters.tsx /features todoSlice.ts /store store.ts App.tsx index.css index.tsx 

React组件设计

1. 主组件(App.tsx)

import { Provider } from 'react-redux'; import { store } from './store/store'; import TodoList from './components/TodoList'; import AddTodo from './components/AddTodo'; import Filters from './components/Filters'; function App() { return ( <Provider store={store}> <div className="app-container"> <h1>Redux ToDo List</h1> <Filters /> <AddTodo /> <TodoList /> </div> </Provider> ); } 

2. 待办项组件(TodoItem.tsx)

import { useDispatch } from 'react-redux'; import { toggleComplete, deleteTodo } from '../features/todoSlice'; interface TodoItemProps { id: string; text: string; completed: boolean; } const TodoItem = ({ id, text, completed }: TodoItemProps) => { const dispatch = useDispatch(); return ( <li className={`todo-item ${completed ? 'completed' : ''}`}> <input type="checkbox" checked={completed} onChange={() => dispatch(toggleComplete(id))} /> <span>{text}</span> <button onClick={() => dispatch(deleteTodo(id))}>×</button> </li> ); }; 

Redux状态管理

1. 创建Store(store.ts)

import { configureStore } from '@reduxjs/toolkit'; import todoReducer from '../features/todoSlice'; export const store = configureStore({ reducer: { todos: todoReducer } }); export type RootState = ReturnType<typeof store.getState>; export type AppDispatch = typeof store.dispatch; 

2. 定义Slice(todoSlice.ts)

import { createSlice, PayloadAction } from '@reduxjs/toolkit'; interface Todo { id: string; text: string; completed: boolean; } interface TodoState { todos: Todo[]; filter: 'all' | 'active' | 'completed'; } const initialState: TodoState = { todos: [], filter: 'all' }; const todoSlice = createSlice({ name: 'todos', initialState, reducers: { addTodo: (state, action: PayloadAction<string>) => { const newTodo: Todo = { id: Date.now().toString(), text: action.payload, completed: false }; state.todos.push(newTodo); }, toggleComplete: (state, action: PayloadAction<string>) => { const todo = state.todos.find(t => t.id === action.payload); if (todo) { todo.completed = !todo.completed; } }, deleteTodo: (state, action: PayloadAction<string>) => { state.todos = state.todos.filter(todo => todo.id !== action.payload); }, setFilter: (state, action: PayloadAction<'all' | 'active' | 'completed'>) => { state.filter = action.payload; } } }); export const { addTodo, toggleComplete, deleteTodo, setFilter } = todoSlice.actions; export default todoSlice.reducer; 

功能实现详解

1. 添加待办事项(AddTodo.tsx)

import { useState } from 'react'; import { useDispatch } from 'react-redux'; import { addTodo } from '../features/todoSlice'; const AddTodo = () => { const [input, setInput] = useState(''); const dispatch = useDispatch(); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (input.trim()) { dispatch(addTodo(input)); setInput(''); } }; return ( <form onSubmit={handleSubmit} className="add-todo-form"> <input type="text" value={input} onChange={(e) => setInput(e.target.value)} placeholder="Add a new todo..." /> <button type="submit">Add</button> </form> ); }; 

2. 筛选功能实现(Filters.tsx)

import { useDispatch, useSelector } from 'react-redux'; import { setFilter } from '../features/todoSlice'; import { RootState } from '../store/store'; const Filters = () => { const dispatch = useDispatch(); const filter = useSelector((state: RootState) => state.todos.filter); return ( <div className="filters"> <button className={filter === 'all' ? 'active' : ''} onClick={() => dispatch(setFilter('all'))} > All </button> <button className={filter === 'active' ? 'active' : ''} onClick={() => dispatch(setFilter('active'))} > Active </button> <button className={filter === 'completed' ? 'active' : ''} onClick={() => dispatch(setFilter('completed'))} > Completed </button> </div> ); }; 

3. 列表渲染与筛选(TodoList.tsx)

import { useSelector } from 'react-redux'; import { RootState } from '../store/store'; import TodoItem from './TodoItem'; const TodoList = () => { const { todos, filter } = useSelector((state: RootState) => state.todos); const filteredTodos = todos.filter(todo => { if (filter === 'all') return true; if (filter === 'active') return !todo.completed; return todo.completed; }); return ( <ul className="todo-list"> {filteredTodos.length > 0 ? ( filteredTodos.map(todo => ( <TodoItem key={todo.id} {...todo} /> )) ) : ( <li className="empty-message">No todos found</li> )} </ul> ); }; 

样式优化

基础CSS样式(index.css)

.app-container { max-width: 600px; margin: 0 auto; padding: 20px; font-family: Arial, sans-serif; } .add-todo-form { display: flex; margin-bottom: 20px; } .add-todo-form input { flex: 1; padding: 10px; font-size: 16px; } .add-todo-form button { padding: 10px 20px; background: #4CAF50; color: white; border: none; cursor: pointer; } .todo-list { list-style: none; padding: 0; } .todo-item { display: flex; align-items: center; padding: 10px; border-bottom: 1px solid #eee; } .todo-item.completed span { text-decoration: line-through; color: #888; } .todo-item input { margin-right: 10px; } .todo-item button { margin-left: auto; background: #f44336; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer; } .filters { margin-bottom: 20px; } .filters button { padding: 5px 15px; margin-right: 5px; background: #f0f0f0; border: 1px solid #ddd; cursor: pointer; } .filters button.active { background: #2196F3; color: white; } 

项目扩展思路

1. 添加本地存储持久化

// 在store.ts中添加 const loadState = () => { try { const serializedState = localStorage.getItem('reduxState'); return serializedState ? JSON.parse(serializedState) : undefined; } catch (err) { return undefined; } }; const store = configureStore({ reducer: { todos: todoReducer }, preloadedState: loadState() }); store.subscribe(() => { localStorage.setItem('reduxState', JSON.stringify(store.getState())); }); 

2. 添加编辑功能

// 在todoSlice.ts中添加reducer editTodo: (state, action: PayloadAction<{id: string; text: string}>) => { const todo = state.todos.find(t => t.id === action.payload.id); if (todo) { todo.text = action.payload.text; } } // 在TodoItem组件中添加编辑逻辑 const [isEditing, setIsEditing] = useState(false); const [editText, setEditText] = useState(text); const handleEdit = () => { if (isEditing) { dispatch(editTodo({ id, text: editText })); } setIsEditing(!isEditing); }; 

常见问题解决

1. 状态更新但视图不刷新

  • 确保没有直接修改state,Redux要求不可变更新
  • 使用Redux Toolkit的createSlice可以自动处理不可变更新

2. TypeScript类型错误

  • 明确定义组件props类型
  • 使用RootState和AppDispatch类型

3. 性能优化

  • 对于大型列表,使用React.memo优化组件
  • 考虑使用reselect创建记忆化selector

总结

通过本教程,我们完整实现了一个基于React+Redux的ToDoList应用,涵盖了:

  1. React组件化开发:合理拆分UI组件
  2. Redux状态管理:使用Redux Toolkit简化流程
  3. 类型安全:全面采用TypeScript
  4. 用户交互:实现完整的CRUD操作
  5. 样式设计:创建美观的界面

这个项目可以作为学习React+Redux的起点,后续可以继续扩展: - 添加用户认证 - 实现后端API连接 - 增加拖拽排序功能 - 添加分类标签系统

希望本文能帮助你掌握React+Redux的核心开发模式,为构建更复杂的应用打下坚实基础。 “`

注:实际字数约5500字,完整实现了Markdown格式的技术文章,包含代码示例、解释说明和结构化内容。如需调整内容细节或扩展特定部分,可以进一步修改完善。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI