React-Redux 基础教程:从零实现 Todo 应用
作为 React 生态中最流行的状态管理方案,React-Redux 为 React 应用提供了与 Redux 集成的能力。本文将带你从零开始,通过实现一个完整的 Todo 应用,掌握 React-Redux 的核心用法。
应用架构设计
在开始编码前,我们先规划应用的整体结构。我们的 Todo 应用将包含以下核心组件:
- TodoApp - 应用的根组件,包含所有子组件
- AddTodo - 负责添加新待办事项
- TodoList - 展示待办事项列表
- Todo - 单个待办事项的展示与交互
- VisibilityFilters - 过滤不同状态的待办事项
Redux Store 设计
Redux 部分遵循标准设计模式:
// store 结构
{
todos: {
byIds: {
"1": { id: 1, content: "学习React", completed: false },
"2": { id: 2, content: "学习Redux", completed: true }
},
allIds: ["1", "2"]
},
visibilityFilter: "SHOW_ALL"
}
核心概念实现
-
Action Creators - 创建修改状态的指令
// 添加待办事项 export const addTodo = (content) => ({ type: "ADD_TODO", payload: { id: generateId(), content } });
-
Reducers - 定义状态如何更新
// todos reducer const todosReducer = (state = initialState, action) => { switch (action.type) { case "ADD_TODO": return { ...state, byIds: { ...state.byIds, [action.payload.id]: action.payload }, allIds: [...state.allIds, action.payload.id] }; // 其他case... } };
-
Selectors - 从store中获取派生数据
// 获取所有待办事项 export const getTodos = (state) => state.todos.allIds.map(id => state.todos.byIds[id]);
连接React与Redux
1. 提供Store
使用Provider
组件使整个应用能访问Redux store:
import { Provider } from 'react-redux';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<TodoApp />
</Provider>,
document.getElementById('root')
);
2. 连接组件
React-Redux的核心是connect
函数,它有四种常见使用方式:
| 场景 | 不订阅store | 订阅store | |------|------------|----------| | 不注入actions | connect()(Comp)
| connect(mapState)(Comp)
| | 注入actions | connect(null, actions)(Comp)
| connect(mapState, actions)(Comp)
|
示例:连接AddTodo组件
import { connect } from 'react-redux';
import { addTodo } from '../actions';
class AddTodo extends React.Component {
handleSubmit = () => {
this.props.addTodo(this.state.input); // 自动dispatch
}
// ...
}
export default connect(null, { addTodo })(AddTodo);
示例:连接TodoList组件
import { connect } from 'react-redux';
import { getVisibleTodos } from '../selectors';
const TodoList = ({ todos }) => (
<ul>{todos.map(todo => <Todo key={todo.id} {...todo} />)}</ul>
);
const mapState = (state) => ({
todos: getVisibleTodos(state)
});
export default connect(mapState)(TodoList);
性能优化技巧
-
精细化mapStateToProps - 只订阅组件真正需要的数据
-
使用记忆化Selectors - 避免不必要的重新计算
import { createSelector } from 'reselect'; const getTodos = state => state.todos.allIds; const getTodoById = state => state.todos.byIds; export const getVisibleTodos = createSelector( [getTodos, getTodoById, (_, filter) => filter], (allIds, byIds, filter) => { // 只有当相关数据变化时才重新计算 } );
-
避免在mapStateToProps中创建新对象 - 使用记忆化或确保引用稳定
完整实现流程
- 设置Redux store - 包含reducers、actions和selectors
- 创建UI组件 - 实现纯展示逻辑
- 连接组件 - 使用connect注入所需数据和actions
- 处理用户交互 - 通过props调用注入的action creators
- 响应状态变化 - 组件自动在相关state变化时重新渲染
通过这个Todo应用的完整实现,你应该已经掌握了React-Redux的核心概念。记住,良好的Redux架构关键在于:
- 合理的store结构设计
- 精确的组件订阅范围
- 高效的派生数据计算
- 清晰的action定义
这些原则将帮助你构建可维护、高性能的React-Redux应用。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考