Redux知识点详细笔记

以下是针对零基础学习者的 Redux 知识点详细笔记,包含核心概念、工作原理、基础实现和 Redux Toolkit 的简化用法,帮助您从零开始理解 Redux 的完整流程。


一、为什么需要 Redux?

1. 问题背景

  • 组件间状态共享困难:当多个组件需要访问或修改同一状态时,通过 props 逐层传递会非常繁琐(“prop drilling”)。
  • 状态管理混乱:随着应用复杂度的增加,状态分散在不同组件中,难以维护和调试。
  • 可预测性差:状态变化没有统一的规则,容易导致难以追踪的 bug。

2. Redux 的核心思想

  • 集中管理状态:将所有状态存储在唯一的 Store 中。
  • 单向数据流:状态只能通过预定义的规则(Reducer)修改,确保可预测性。
  • 组件按需订阅:组件只订阅与自己相关的状态,减少不必要的渲染。

二、Redux 核心概念

1. 三大核心要素

名称作用类比解释
Store存储全局状态的容器相当于应用的“数据库”
Action描述状态变化的普通对象(包含 type 和可选的 payload相当于“操作指令”(如“存钱”)
Reducer纯函数,接收当前状态和 Action,返回新状态(不可直接修改原状态)相当于“银行柜员处理指令”

2. Redux 三大原则

  1. 单一数据源:整个应用的状态存储在唯一 Store 中。
  2. 状态只读:唯一修改状态的方式是派发 Action。
  3. 纯函数修改:Reducer 必须是纯函数,无副作用,不可修改原状态。

三、Redux 基础实现(无 Redux Toolkit)

1. 手动实现一个计数器

(1) 定义 Action Types
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
(2) 定义 Action Creators
const increment = () => ({ type: INCREMENT });
const decrement = () => ({ type: DECREMENT });
(3) 定义 Reducer
const initialState = { count: 0 };

function counterReducer(state = initialState, action) {
  switch (action.type) {
    case INCREMENT:
      return { ...state, count: state.count + 1 }; // ✅ 不可变更新
    case DECREMENT:
      return { ...state, count: state.count - 1 };
    default:
      return state;
  }
}
(4) 创建 Store
import { createStore } from 'redux';

const store = createStore(counterReducer);
(5) 组件中使用
// 订阅状态变化
store.subscribe(() => {
  console.log('Current state:', store.getState());
});

// 派发 Action
store.dispatch(increment()); // { count: 1 }
store.dispatch(decrement()); // { count: 0 }

四、Redux Toolkit 简化实现

1. Redux Toolkit 核心工具

工具作用
configureStore简化 Store 创建(自动集成中间件、DevTools)
createSlice自动生成 Reducer 和 Action(减少样板代码)
createAsyncThunk处理异步操作(如 API 请求)

2. 用 Redux Toolkit 重构计数器

(1) 创建 Slice
// counterSlice.js
import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { count: 0 },
  reducers: {
    increment: (state) => {
      state.count += 1; // ✅ 直接修改(内部使用 Immer 处理不可变性)
    },
    decrement: (state) => {
      state.count -= 1;
    },
  },
});

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
(2) 创建 Store
// store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';

export const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
});
(3) 在 React 组件中使用
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';

function Counter() {
  const count = useSelector((state) => state.counter.count);
  const dispatch = useDispatch();

  return (
    <div>
      <button onClick={() => dispatch(decrement())}>-</button>
      <span>{count}</span>
      <button onClick={() => dispatch(increment())}>+</button>
    </div>
  );
}

五、Redux 数据流详解

1. 流程图

组件 → dispatch(Action) → Store → Reducer → 更新 State → 通知订阅者 → 组件更新

2. 分步解释

  1. 组件触发事件(如点击按钮)→ 调用 dispatch(action)
  2. Store 接收 Action → 调用对应的 Reducer。
  3. Reducer 根据 Action 类型 → 返回新的状态。
  4. Store 更新状态 → 通知所有订阅了该状态的组件。
  5. 组件重新渲染 → 使用新状态更新 UI。

六、异步操作(使用 createAsyncThunk

1. 处理 API 请求

// postsSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

// 定义异步 Action
export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => {
  const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
  return response.data;
});

const postsSlice = createSlice({
  name: 'posts',
  initialState: { data: [], loading: false, error: null },
  extraReducers: (builder) => {
    builder
      .addCase(fetchPosts.pending, (state) => {
        state.loading = true;
      })
      .addCase(fetchPosts.fulfilled, (state, action) => {
        state.loading = false;
        state.data = action.payload;
      })
      .addCase(fetchPosts.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message;
      });
  },
});

export default postsSlice.reducer;

2. 组件中触发异步请求

import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchPosts } from './postsSlice';

function PostsList() {
  const dispatch = useDispatch();
  const { data, loading, error } = useSelector((state) => state.posts);

  useEffect(() => {
    dispatch(fetchPosts());
  }, [dispatch]);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <ul>
      {data.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

七、项目结构组织

推荐结构

src/
├── app/
│   └── store.js          // Store 配置
├── features/             // 按功能模块划分
│   ├── counter/          // 计数器模块
│   │   ├── counterSlice.js
│   │   └── Counter.jsx
│   └── posts/            // 文章模块
│       ├── postsSlice.js
│       └── PostsList.jsx
└── index.js              // 应用入口

八、常见问题解答

1. Redux 必须用于所有项目吗?

  • 小型项目:使用 React 的 useState 或 Context API 即可。
  • 中大型项目:Redux 更适合管理复杂状态和异步逻辑。

2. 直接修改状态为什么合法?

Redux Toolkit 内部使用 Immer 库,允许在 Reducer 中直接修改 state,但最终会生成一个全新的不可变对象。

3. 如何调试?

  • 安装 Redux DevTools 浏览器扩展 → 自动集成到 Redux Toolkit 的 Store。
  • 查看 Action 派发记录和状态变化历史。

九、总结

Redux 核心流程

  1. 定义状态 → 创建 Store。
  2. 派发 Action → 描述状态变化。
  3. Reducer 处理 → 返回新状态。
  4. 组件订阅 → 按需更新 UI。

Redux Toolkit 优势

  • 代码简洁:减少 70% 的样板代码。
  • 开箱即用:集成中间件、DevTools、Immer。
  • 异步友好createAsyncThunk 简化异步逻辑。

通过掌握这些核心概念,您已经能够使用 Redux 和 Redux Toolkit 构建可预测、易维护的状态管理系统!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值