Skip to content

Redux

Redux 状态更新流程可以概括为一个单向数据流 (one-way data flow),主要分为 5 个关键步骤


🧭 一图概览

UI 组件 -> dispatch(action) -> reducer -> new state -> store 通知订阅者 -> UI 重新渲染

💡 流程详细说明

① 用户触发 Action

当用户在界面上执行操作(比如点击按钮、输入文本等), 组件通过 dispatch() 方法发送一个 action 对象

js
dispatch({ type: 'INCREMENT' })

Action 是一个普通的 JavaScript 对象,至少包含一个 type 属性,用来描述发生了什么。


② Store 接收到 Action

Redux 的 store 是应用状态的唯一来源。 当调用 store.dispatch(action) 时,store 会把这个 action 交给 reducer 来处理。


③ Reducer 处理状态更新

Reducer 是一个纯函数,根据当前 state 和传入的 action,返回一个新的状态:

js
function counterReducer(state = { count: 0 }, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 }
    case 'DECREMENT':
      return { count: state.count - 1 }
    default:
      return state
  }
}

⚠️ 重要:Reducer 不能直接修改原 state,必须返回一个新对象(不可变性原则)。


④ Store 更新并保存新状态

Reducer 返回的新 state 会替换掉旧 state, Redux 内部会存储这个新状态,并触发通知。


⑤ 订阅者 (UI 层) 被通知

所有通过 store.subscribe() 注册的监听函数(例如 React 组件中的 useSelector) 都会被调用,从 store 获取最新的 state,然后触发 UI 重新渲染

例如,在 React 中:

jsx
const count = useSelector(state => state.count)

当 store 的状态改变时,这个组件会自动重新渲染以反映最新数据。


🧩 可视化理解

用户操作

dispatch(action)

reducer(state, action)

返回新 state

store 更新

UI 重新渲染

redux 创建reducer

js
// store.js
import { createStore } from 'redux'

// 1. 定义初始状态
const initialState = {
  count: 0
}

// 2. 定义 reducer (纯函数)
function counterReducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 }
    case 'DECREMENT':
      return { count: state.count - 1 }
    default:
      return state
  }
}

// 3. 创建 store
const store = createStore(counterReducer)

// 导出 store
export default store

redux-tooltik 创建reducer

js


import { createSlice , createAsyncThunk } from '@reduxjs/toolkit'
import { getDiscount, getGoodPrice, getHighScore, getHomeHotRecommendData, getHomeLongforData } from '@/services/modules/home';
export const fetchHomeData = createAsyncThunk('goodPriceData', (payload,{dispatch,getState})=>{
     getGoodPrice().then(res=>{
        dispatch(goodPriceAction(res))
     })
     getHighScore().then(res=>{
        dispatch(highscoreAction(res))
     })
     getDiscount().then(res=>{
        dispatch(discountAction(res))
     })
     getHomeHotRecommendData().then(res=>{
        dispatch(HotRecommendAction(res))
     })
     getHomeLongforData().then(res=>{
        console.log(res);
        dispatch(longForAction(res))
     })
})

const homeSlice = createSlice({
  name: "home",
  initialState: {
    goodPrice:{},
    highScore:{},
    disCount:{},
    hotRecommend:{},
    longFor:{}
  },
  reducers: {
    goodPriceAction(state,{payload}){
        state.goodPrice = payload
    },
    highscoreAction(state,{payload}){
        state.highScore = payload
    },
    discountAction(state,{payload}){
        state.disCount = payload
    },
    HotRecommendAction(state,{payload}){
      state.hotRecommend = payload
    },
    longForAction(state,{payload}){
      state.longFor = payload
    }
  },
})
export const {goodPriceAction,highscoreAction,discountAction,HotRecommendAction,longForAction} = homeSlice.actions

export default homeSlice.reducer

案例

https://github.com/dargon-start/lz-airbnd/tree/main/src/store