React-Redux 基础教程:标准 Redux 模式解析
redux 项目地址: https://gitcode.com/gh_mirrors/red/redux
前言
在前面的章节中,我们已经学习了 Redux 的核心概念和工作原理。本文将深入探讨在实际 React-Redux 项目中常用的几种标准模式,这些模式虽然不是必须的,但能显著提升代码的可维护性和性能。
一、Action Creators(动作创建器)
1.1 什么是 Action Creators
Action Creators 是创建和返回 action 对象的函数。它们封装了 action 对象的创建逻辑,使得我们不必每次都手动编写 action 对象。
// 原始方式
dispatch({ type: 'todos/todoAdded', payload: 'Buy milk' })
// 使用 Action Creator
const todoAdded = text => ({
type: 'todos/todoAdded',
payload: text
})
dispatch(todoAdded('Buy milk'))
1.2 使用 Action Creators 的优势
- 代码复用:避免重复编写相同的 action 对象结构
- 逻辑封装:可以在创建 action 时添加额外处理逻辑
- 一致性:确保 action 的结构始终正确
- 可测试性:更容易对 action 创建逻辑进行单元测试
1.3 实际应用示例
在 todo 应用中,我们可以这样重构:
// todosSlice.js
export const todoAdded = todo => ({
type: 'todos/todoAdded',
payload: todo
})
// 组件中使用
import { todoAdded } from './todosSlice'
dispatch(todoAdded(newTodo))
二、Memoized Selectors(记忆化选择器)
2.1 选择器性能问题
当我们在组件中使用 useSelector 时,每次 action 分发后选择器都会重新执行。如果选择器返回新对象或数组(如使用 map、filter 等),即使数据实际未变,也会导致组件不必要的重新渲染。
// 每次都会返回新数组,导致不必要的重渲染
const selectTodoIds = state => state.todos.map(todo => todo.id)
2.2 Reselect 解决方案
Reselect 库提供了 createSelector
函数来创建记忆化选择器:
npm install reselect
2.3 创建记忆化选择器
import { createSelector } from 'reselect'
export const selectTodoIds = createSelector(
state => state.todos, // 输入选择器
todos => todos.map(todo => todo.id) // 输出选择器
)
2.4 复杂选择器示例
结合多个过滤条件的选择器:
export const selectFilteredTodos = createSelector(
state => state.todos,
state => state.filters.status,
state => state.filters.colors,
(todos, status, colors) => {
// 复杂的过滤逻辑...
}
)
三、请求状态跟踪
3.1 常见的加载状态模式
在异步操作中,我们通常需要跟踪以下状态:
- 'idle' - 初始状态,无操作进行
- 'loading' - 请求进行中
- 'succeeded' - 请求成功
- 'failed' - 请求失败
3.2 实现方式
const initialState = {
status: 'idle',
error: null
// ...其他状态
}
const todosSlice = {
// ...
extraReducers: {
[fetchTodos.pending]: (state) => {
state.status = 'loading'
},
[fetchTodos.fulfilled]: (state, action) => {
state.status = 'succeeded'
// 处理数据
},
[fetchTodos.rejected]: (state, action) => {
state.status = 'failed'
state.error = action.error.message
}
}
}
四、状态规范化
4.1 为什么需要规范化
当处理嵌套或关联数据时,规范化状态可以:
- 避免数据重复
- 使更新更简单
- 提升性能
4.2 规范化结构示例
{
todos: {
ids: [1, 2, 3],
entities: {
1: {id: 1, text: "Buy milk", completed: false},
2: {id: 2, text: "Write blog post", completed: true},
3: {id: 3, text: "Do laundry", completed: false}
}
}
}
五、Thunk 与 Promise 处理
5.1 Thunk 模式进阶
export const fetchTodos = () => async dispatch => {
try {
dispatch(todosLoading())
const response = await api.getTodos()
dispatch(todosLoaded(response.data))
} catch (err) {
dispatch(todosLoadFailed(err.message))
}
}
5.2 错误处理最佳实践
- 捕获所有可能的错误
- 分发明确的错误 action
- 在 reducer 中处理错误状态
- 在组件中显示有意义的错误信息
总结
本文介绍的标准 Redux 模式包括:
- Action Creators:封装 action 创建逻辑
- Memoized Selectors:优化性能,避免不必要的重渲染
- 请求状态跟踪:清晰地管理异步操作状态
- 状态规范化:优化数据结构
- Thunk 处理:优雅地处理异步逻辑
这些模式共同构成了生产级 Redux 应用的基础。在下一部分,我们将探讨如何用 Redux Toolkit 简化这些模式。
redux 项目地址: https://gitcode.com/gh_mirrors/red/redux
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考