React-Redux基础教程:构建Todo应用实战指南
react-redux 项目地址: https://gitcode.com/gh_mirrors/rea/react-redux
前言
在现代前端开发中,状态管理是构建复杂应用的关键环节。React-Redux作为React与Redux之间的桥梁,提供了一套优雅的解决方案。本文将通过一个完整的Todo应用示例,带你深入理解React-Redux的核心概念和使用方法。
应用架构概览
我们的Todo应用由以下几个核心部分组成:
React组件树
- TodoApp:应用根组件,协调所有子组件
- AddTodo:负责添加新待办事项
- TodoList:展示待办事项列表
- Todo:单个待办事项的展示与交互
- VisibilityFilters:提供筛选功能(全部/已完成/未完成)
Redux状态管理
-
Store结构:
todos
:规范化存储的待办事项byIds
:以ID为键的对象映射allIds
:维护顺序的ID数组
visibilityFilters
:当前筛选条件
-
Action Creators:
addTodo
:添加新待办事项toggleTodo
:切换完成状态setFilter
:设置筛选条件
核心实现步骤
1. 提供Store给应用
首先需要让整个React应用能够访问Redux store,这是通过Provider
组件实现的:
import { Provider } from 'react-redux';
import store from './redux/store';
ReactDOM.render(
<Provider store={store}>
<TodoApp />
</Provider>,
document.getElementById('root')
);
Provider
使用了React的Context API,使得任何子组件都能访问到store,而不需要显式地逐层传递。
2. 连接组件与Store
React-Redux提供了connect
高阶组件(HOC)来连接React组件与Redux store。connect
接收两个主要参数:
mapStateToProps
将store中的state映射为组件的props。当store更新时,这个函数会被调用,返回的对象将作为props传递给组件。
const mapStateToProps = (state) => ({
todos: getVisibleTodos(state)
});
mapDispatchToProps
将action creators映射为组件的props。可以是一个对象或函数:
// 对象简写形式
const mapDispatchToProps = {
addTodo,
toggleTodo
};
// 或函数形式
const mapDispatchToProps = (dispatch) => ({
addTodo: (text) => dispatch(addTodo(text))
});
3. 实现AddTodo组件
class AddTodo extends React.Component {
state = { input: '' };
handleAddTodo = () => {
this.props.addTodo(this.state.input);
this.setState({ input: '' });
};
render() {
return (
<div>
<input
value={this.state.input}
onChange={(e) => this.setState({ input: e.target.value })}
/>
<button onClick={this.handleAddTodo}>Add Todo</button>
</div>
);
}
}
export default connect(null, { addTodo })(AddTodo);
这里我们只关心派发action,不需要订阅store,所以mapStateToProps
为null。
4. 实现TodoList组件
const TodoList = ({ todos }) => (
<ul>
{todos.map((todo) => (
<Todo key={todo.id} {...todo} />
))}
</ul>
);
const mapStateToProps = (state) => ({
todos: getTodosByVisibilityFilter(state, state.visibilityFilter)
});
export default connect(mapStateToProps)(TodoList);
这里我们使用了selector函数getTodosByVisibilityFilter
来根据当前筛选条件过滤待办事项。
5. 实现Todo组件
const Todo = ({ id, content, completed, toggleTodo }) => (
<li
onClick={() => toggleTodo(id)}
style={{ textDecoration: completed ? 'line-through' : 'none' }}
>
{content}
</li>
);
export default connect(null, { toggleTodo })(Todo);
6. 实现VisibilityFilters组件
const VisibilityFilters = ({ activeFilter, setFilter }) => (
<div>
{Object.values(VISIBILITY_FILTERS).map((filter) => (
<span
key={filter}
onClick={() => setFilter(filter)}
style={{
marginRight: 10,
fontWeight: filter === activeFilter ? 'bold' : 'normal'
}}
>
{filter}
</span>
))}
</div>
);
const mapStateToProps = (state) => ({
activeFilter: state.visibilityFilter
});
export default connect(mapStateToProps, { setFilter })(VisibilityFilters);
性能优化建议
-
使用记忆化Selector:对于复杂的数据转换,使用Reselect库创建记忆化selector,避免不必要的重复计算。
-
组件拆分:将大型组件拆分为多个小组件,只有真正需要访问store的组件才进行连接。
-
浅比较优化:确保
mapStateToProps
返回的对象不会在state未变化时产生新的引用。
常见连接模式总结
| 场景 | 不订阅store | 订阅store | |------|------------|-----------| | 不注入action creators | connect()(Component)
| connect(mapStateToProps)(Component)
| | 注入action creators | connect(null, mapDispatchToProps)(Component)
| connect(mapStateToProps, mapDispatchToProps)(Component)
|
总结
通过这个Todo应用的完整实现,我们学习了React-Redux的核心概念:
- 使用
Provider
使store对整个应用可用 - 使用
connect
高阶组件连接React组件与Redux store - 通过
mapStateToProps
订阅store状态 - 通过
mapDispatchToProps
注入action creators - 使用selector函数组织和派生数据
React-Redux的这种设计模式,既保持了组件与状态管理的分离,又提供了简洁的集成方式,是构建可维护React应用的强大工具。
react-redux 项目地址: https://gitcode.com/gh_mirrors/rea/react-redux
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考