Redux Toolkit 用法、解决原生Redux 冗余问题

Redux Toolkit(RTK) 是 Redux Toolkit 官方推荐的 Redux 开发方式,用来解决原生 Redux 配置复杂、模板代码过多的问题。


一、原生 Redux 为什么"冗余"

传统 Redux 一个简单计数器,通常要写:

1. actionTypes

复制代码
export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'

2. actions

复制代码
export const increment = () => ({
  type: INCREMENT
})

export const decrement = () => ({
  type: DECREMENT
})

3. reducer

复制代码
const initState = {
  count: 0
}

export default function reducer(state = initState, 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, combineReducers } from 'redux'

const store = createStore(rootReducer)

问题:

  • action type 重复

  • action creator 重复

  • switch-case 冗长

  • immutable 更新麻烦

  • store 配置复杂

  • thunk middleware 还得手动装

所以 Redux Toolkit 出来了。


二、Redux Toolkit 核心思想

RTK 帮你:

✅ 自动生成 action

✅ 自动处理 immutable

✅ 自动配置 thunk

✅ 简化 reducer

✅ 简化 store

✅ 规范化 Redux 写法


三、Redux Toolkit 核心 API

最常用:

API 作用
configureStore 创建 store
createSlice 创建 reducer + action
createAsyncThunk 处理异步
useSelector 获取状态
useDispatch 派发 action

四、Redux Toolkit 基础用法


1. 安装

复制代码
npm install @reduxjs/toolkit react-redux

2. 创建 slice

counterSlice.js

复制代码
import { createSlice } from '@reduxjs/toolkit'

const counterSlice = createSlice({
  name: 'counter',

  initialState: {
    count: 0
  },

  reducers: {
    increment(state) {
      state.count += 1
    },

    decrement(state) {
      state.count -= 1
    },

    add(state, action) {
      state.count += action.payload
    }
  }
})

export const {
  increment,
  decrement,
  add
} = counterSlice.actions

export default counterSlice.reducer

createSlice 做了什么

它自动帮你生成:

action

复制代码
increment()

自动生成:

复制代码
{
  type: 'counter/increment'
}

reducer

内部自动生成:

复制代码
switch(action.type)

你不用写了。


五、configureStore

store.js

复制代码
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from './counterSlice'

export const store = configureStore({
  reducer: {
    counter: counterReducer
  }
})

configureStore 优势

自动:

✅ combineReducers

✅ redux-thunk

✅ Redux DevTools

✅ 中间件配置

原生 Redux:

复制代码
createStore(
  rootReducer,
  applyMiddleware(thunk)
)

RTK:

复制代码
configureStore()

结束。


六、React 中使用


1. Provider 注入

main.jsx

复制代码
import ReactDOM from 'react-dom/client'
import { Provider } from 'react-redux'
import { store } from './store'

root.render(
  <Provider store={store}>
    <App />
  </Provider>
)

2. 页面使用

Counter.jsx

复制代码
import { useSelector, useDispatch } from 'react-redux'
import { increment, decrement, add } from './counterSlice'

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

  const dispatch = useDispatch()

  return (
    <div>
      <h1>{count}</h1>

      <button onClick={() => dispatch(increment())}>
        +
      </button>

      <button onClick={() => dispatch(decrement())}>
        -
      </button>

      <button onClick={() => dispatch(add(10))}>
        +10
      </button>
    </div>
  )
}

七、为什么 RTK 可以直接修改 state?

这里很多人误解。

你看到:

复制代码
state.count += 1

实际上 Redux 仍然是不可变的。

RTK 内部用了:

Immer

Immer

它会:

复制代码
state.count += 1

自动转换成:

复制代码
return {
  ...state,
  count: state.count + 1
}

所以:

✅ 写法像"可变"

✅ 实际还是 immutable


八、异步请求 createAsyncThunk

这是 RTK 最大优势之一。


原生 Redux 异步

需要:

  • redux-thunk

  • loading

  • success

  • fail

  • actionTypes

  • actionCreators

非常繁琐。


RTK 写法

userSlice.js

复制代码
import {
  createSlice,
  createAsyncThunk
} from '@reduxjs/toolkit'

export const fetchUser = createAsyncThunk(
  'user/fetchUser',

  async (id) => {
    const res = await fetch(
      `https://jsonplaceholder.typicode.com/users/${id}`
    )

    return await res.json()
  }
)

const userSlice = createSlice({
  name: 'user',

  initialState: {
    user: null,
    loading: false
  },

  reducers: {},

  extraReducers: (builder) => {
    builder
      .addCase(fetchUser.pending, (state) => {
        state.loading = true
      })

      .addCase(fetchUser.fulfilled, (state, action) => {
        state.loading = false
        state.user = action.payload
      })

      .addCase(fetchUser.rejected, (state) => {
        state.loading = false
      })
  }
})

export default userSlice.reducer

自动生成三种状态

RTK 自动帮你生成:

复制代码
fetchUser.pending
fetchUser.fulfilled
fetchUser.rejected

不用手写。


九、RTK 项目推荐目录结构

复制代码
src
 ├── store
 │    ├── index.js
 │    ├── userSlice.js
 │    └── counterSlice.js
 │
 ├── pages
 ├── components
 └── App.jsx

大型项目:

复制代码
src
 ├── store
 │    ├── modules
 │    │     ├── user
 │    │     │    ├── index.js
 │    │     │    ├── actions.js
 │    │     │    └── selectors.js

十、RTK vs 原生 Redux

对比 原生 Redux Redux Toolkit
action types 手写 自动生成
reducer switch-case createSlice
immutable 手动展开 Immer 自动
store配置 复杂 configureStore
thunk 手动装 默认内置
代码量 很多 很少
官方推荐

十一、现在企业基本怎么用?

现在 React 项目:

大部分:

复制代码
React + Redux Toolkit + React-Redux

而不是:

复制代码
React + Redux

RTK 已经是 Redux 官方标准。


十二、你现在最该掌握的

真正工作高频:

必会

  • createSlice

  • configureStore

  • useSelector

  • useDispatch

  • createAsyncThunk


进阶

  • RTK Query

  • middleware

  • redux-persist

  • selector优化

  • normalize 数据结构


十三、面试高频问题


1. Redux Toolkit 为什么解决 Redux 冗余?

核心:

  • 自动生成 action

  • 自动 immutable

  • 不用 switch-case

  • store 自动配置

  • thunk 默认集成


2. createSlice 做了什么?

同时生成:

  • reducer

  • actions

  • action types


3. RTK 为什么能直接修改 state?

因为内部使用了:

Immer


4. createAsyncThunk 有什么作用?

简化:

  • loading

  • success

  • fail

异步状态管理。


十四、推荐你现在这样学习

你有 React 基础的话,建议路线:

复制代码
Redux 基础原理
    ↓
Redux Toolkit
    ↓
createAsyncThunk
    ↓
RTK Query
    ↓
项目实战

十五、一个最简 RTK 工作流

复制代码
createSlice
    ↓
生成 reducer + actions
    ↓
configureStore 注册
    ↓
Provider 注入
    ↓
组件 useSelector/useDispatch
相关推荐
KANGBboy1 小时前
java知识二(数组)
java·开发语言·python
云水一下1 小时前
JavaScript 从零基础到精通系列:DOM 操作与事件驱动编程
前端·javascript
零陵上将军_xdr1 小时前
后端转全栈学习-Day3-JavaScript 基础-1
开发语言·javascript·学习
GISHUB1 小时前
Express + TypeScript + ESM 后端服务搭建教程
javascript·typescript·express
llilay1 小时前
企业级FastAPI后端模板搭建(二)整合路由Router
开发语言·python·fastapi
不会C语言的男孩2 小时前
C++ Primer Plus 第13章:类继承
开发语言·c++
我材不敲代码2 小时前
Python基础: 函数超全详解:定义、参数、返回值、作用域与递归
开发语言·python·算法
志起计算机编程2 小时前
挖掘单节点Clickhouse极致性能上限
服务器·开发语言·python
Reisentyan2 小时前
[Pro]GoLang Learn Data Day 5
开发语言·后端·golang