React-Redux 基础教程:标准 Redux 模式解析

React-Redux 基础教程:标准 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 的优势

  1. 代码复用:避免重复编写相同的 action 对象结构
  2. 逻辑封装:可以在创建 action 时添加额外处理逻辑
  3. 一致性:确保 action 的结构始终正确
  4. 可测试性:更容易对 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 错误处理最佳实践

  1. 捕获所有可能的错误
  2. 分发明确的错误 action
  3. 在 reducer 中处理错误状态
  4. 在组件中显示有意义的错误信息

总结

本文介绍的标准 Redux 模式包括:

  1. Action Creators:封装 action 创建逻辑
  2. Memoized Selectors:优化性能,避免不必要的重渲染
  3. 请求状态跟踪:清晰地管理异步操作状态
  4. 状态规范化:优化数据结构
  5. Thunk 处理:优雅地处理异步逻辑

这些模式共同构成了生产级 Redux 应用的基础。在下一部分,我们将探讨如何用 Redux Toolkit 简化这些模式。

redux redux 项目地址: https://gitcode.com/gh_mirrors/red/redux

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

解雁淞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值