Skip to content
返回

2025-12-26 Redux 快速学习上手、简单易懂

![[../../../assets/images/pub/rzyd.webp]]

目录

点击展开

Redux 是什么?

官网 https://www.redux.org.cn/(英) https://www.redux.org.cn/(中)

执行流程

![[../../../assets/images/2025/Pasted image 20251226104205.png]]

Redux把整个数据修改的流程分成了三个核心概念:State、Action、Reducer state:一个对象存放数据的管理状态 action:一个对象用来描述如何修改数据 reducer:一个函数根据action的描述生成一个新的state

体验

![[../../../assets/images/2025/redux-demo.gif]]

demo.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button id="decrement">-</button>
  <span id="count">0</span>
  <button id="increment">+</button>

  <script type="module">
    import { createStore } from 'https://cdnjs.cloudflare.com/ajax/libs/redux/5.0.1/redux.legacy-esm.min.js';
    // 1.定义reducer函数
    // 作用:根据不同的action对象,返回不同的新的state  
    // state:管理的数据初始状态
    // action:对象 type 标记当前想要做什么样的修改

    function reducer(state = { count: 0 }, action) {
      // 数据不可变:基于原始状态生成一个新的状态
      switch (action.type) {
        case 'INCREMENT':
          return { count: state.count + 1 }
        case 'DECREMENT':
          return { count: state.count - 1 }
        default:
          return state
      }
    }
    // 2.使用reducer函数生成store实例
    const store = createStore(reducer)
    // 3.通过store实例的subscribe订阅数据变化
    // 回调函数可以在每次state发生变化的时候自动执行
    store.subscribe(() => {
      document.getElementById('count').innerHTML = store.getState().count
      console.log(store.getState())
    })

    // 4.通过store实例的dispatch函数提交action更改状态
    const inBtn = document.getElementById('decrement')
    inBtn.addEventListener('click', () => {
      store.dispatch({ type: 'DECREMENT' })
    })

    const outBtn = document.getElementById('increment')
    outBtn.addEventListener('click', () => {
      store.dispatch({ type: 'INCREMENT' })
    })
  </script>
</body>

</html>

快速上手

术语解析

在我们继续之前,你需要熟悉一些重要的 Redux 术语:

Action

action 是一个具有 type 字段的普通 JavaScript 对象。你可以将 action 视为描述应用程序中发生了什么的事件.

例如体验代码里的 { type: 'DECREMENT' },当然也可以携带数据,请看下面代码:

const addTodoAction = {
  type: "ADD_TODO",
  payload: "Learn Redux",
};

Reducer

reducer 是一个函数,接收当前的 state 和一个 action 对象,必要时决定如何更新状态,并返回新状态(state)。

例如:

function reducer(state = { count: 0 }, action) {
  // 数据不可变:基于原始状态生成一个新的状态
  switch (action.type) {
	case 'INCREMENT':
	  return { count: state.count + 1 }
	case 'DECREMENT':
	  return { count: state.count - 1 }
	default:
	  return state
  }
}

Store

当前 Redux 应用的 state 存在于一个名为 store 的对象中

例如 state = { count: 0 }

Dispatch

Redux store 有一个方法叫 dispatch更新 state 的唯一方法是调用 store.dispatch() 并传入一个 action 对象

例如 store.dispatch({ type: 'INCREMENT' })

数据流更新动图解析

该图来自redux官网提供

![[../../../assets/images/2025/ReduxDataFlowDiagram.BJJTlKEu.gif]]

执行流程

React使用Redux

在React中使用redux,官方要求安装俩个其他插件-ReduxToolkitreact-redux

Redux Toolkit 就是Redux的工具库,使其操作Redux更简便 React-Redux 就是React和Redux之间进行关联的工具

结合使用

为了节省时间可以直接使用 vite提供的模版,现成的环境结合使用;当然如果本地有创建好的项目也可以使用 https://stackblitz.com/edit/vitejs-vite-nmchxbgf?file=index.html&terminal=dev

异步更新数据

接着上面示例写

store/modules/counterStore.ts

import { createSlice } from '@reduxjs/toolkit';
import type { PayloadAction } from '@reduxjs/toolkit';
	
const counterStore = createSlice({
  name: 'counter',
  // 初始化state
  initialState: {
	count: 0,
  },
  reducers: {
	// ...
	 incrementByAmount(state, action: PayloadAction<number>) {
      state.count += action.payload;
    },
  },
});

//解构出来actionCreater函数
const { increment, decrement } = counterStore.actions;
const reducer = counterStore.reducer;

// 模拟异步请求
const incrementAsync = (amount: number) => {
	return (dispatch) => {
	    setTimeout(() => {
	      dispatch(incrementByAmount(amount));
	    }, 1000);
	}
};

export { increment, decrement, incrementAsync };
export default reducer;

app.tsx 在当前文件中引入后使用dispatch更新

 {/* 异步更新数据 */}
<button onClick={() => dispatch(incrementAsync(5))}>
  +100 Async
</button>

解析异步流程 点击按钮后 dispatch(incrementAsync(5)) 详细执行过程

  1. 第一步:incrementAsync(5) 函数调用
    dispatch(incrementAsync(5))

incrementAsync 函数执行 javascript export const incrementAsync = (amount) =>{ return (dispatch) => { setTimeout(() => { dispatch(incrementByAmount(amount)) }, 1000) } }

- amount 参数被设置为 5
- 返回一个**函数**:`(dispatch) => { setTimeout(...) }`

 此时 dispatch 接收到的内容
```javascript
dispatch(  // 接收的是一个函数,而不是普通 action 对象
  (dispatch) => {
    setTimeout(() => {
      dispatch(incrementByAmount(5))
    }, 1000)
  }
)
```

2. 第二步:Redux Thunk 中间件拦截

普通 dispatch vs Thunk dispatch
- **普通 action**:`{ type: 'some-action', payload: data }`
- **Thunk action**:一个函数 `(dispatch, getState) => {}`

Redux 中间件链处理
```javascript
// Redux 中间件检查 dispatch 的内容
if (typeof action === 'function') {
  // 如果是函数,交给 Redux Thunk 处理
  return action(dispatch, getState, extraArgument)
} else {
  // 如果是普通 action,继续传递给 reducer
  return next(action)
}
```

3. 第三步:Redux Thunk 执行返回的函数

函数被立即执行
```javascript
// Redux Thunk 执行:
(dispatch) => {
  setTimeout(() => {
    dispatch(incrementByAmount(5))  // 1秒后执行
  }, 1000)
}
```

 传递 dispatch 参数
- Redux Thunk 将 store 的 dispatch 函数作为参数传入
- 现在函数内部可以使用 dispatch 来派发其他 action

4. 第四步:setTimeout 设置定时器

异步任务启动
```javascript
setTimeout(() => {
  dispatch(incrementByAmount(5))  // 这部分 1 秒后执行
}, 1000)
```

- 设置一个 1000 毫秒的定时器
- **当前 dispatch 调用结束**,函数返回
- 主线程继续执行其他代码

5. 第五步:1 秒后定时器回调执行

定时器到期
```javascript
dispatch(incrementByAmount(5))
```

incrementByAmount 执行流程
1. incrementByAmount 返回 action 对象:
   ```javascript
   { 
     type: 'counter/incrementByAmount', 
     payload: 5 
   }
   ```

2. Redux 正常处理流程:
   - action 通过中间件链
   - 到达 counterSlice 的 reducer
   - 执行 incrementByAmount  reducer 函数:
     ```javascript
     incrementByAmount: (state, action) => {
       state.value += action.payload  // state.value += 5
     }
     ```

1. 状态更新并通知所有订阅的组件

6. 执行时序总结

```
时刻 0ms: dispatch(incrementAsync(5))

时刻 0ms: incrementAsync(5) 返回函数

时刻 0ms: Redux Thunk 拦截并执行函数

时刻 0ms: setTimeout 设置定时器,dispatch 调用结束

时刻 1000ms: 定时器触发

时刻 1000ms: dispatch(incrementByAmount(5))

时刻 1000ms+: 执行 reducer,更新状态,组件重渲染
```

**关键点**:dispatch 调用本身在 0ms 时就完成了,真正的状态更新发生在 1000ms 后。这就是 Redux Thunk 实现异步操作的机制。





到这里就结束了,后续还会更新 React 系列相关,还请持续关注! 感谢阅读,若有错误可以在下方评论区留言哦!!!

![[../../../assets/images/pub/clw.webp#pic_center)]]




Share this post on:

上一篇文章
2025-08-21 Git 常用命令
下一篇文章
2026-01-12 Go结合Gin框架开发Web