React

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > React > Redux Toolkit

Redux Toolkit 实战小结

作者:Csvn

Redux曾是React状态管理的标准解决方案,但传统 Redux 的样板代码过多、配置复杂、异步处理繁琐,Redux Toolkit(RTK)官方推出,旨在解决这些痛点,下面就来详细的介绍一下如何使用

引言

Redux 曾是 React 状态管理的标准解决方案,但传统 Redux 的样板代码过多、配置复杂、异步处理繁琐。Redux Toolkit(RTK)官方推出,旨在解决这些痛点,成为现代 Redux 开发的标准方式。

一、为什么选择 Redux Toolkit?

传统 Redux 的三大痛点

  1. 配置复杂:需要手动配置 store、中间件、devtools
  2. 样板代码多:action types、action creators、reducers 分离
  3. 异步处理 麻烦:需要额外安装 redux-thunk 或 redux-saga

RTK 的优势

特性传统 ReduxRedux Toolkit
Store 配置多行手动配置configureStore 一行搞定
Action 定义手动定义 type + creatorcreateSlice 自动生成
不可变更新需要 spread 运算符Immer 内置,可直接修改
DevTools手动配置自动集成
TypeScript繁琐的类型定义内置类型支持

二、四步实战 Redux Toolkit

步骤 1:安装与 Store 配置

npm install @reduxjs/toolkit react-redux
// src/app/store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
import userReducer from '../features/user/userSlice';
export const store = configureStore({
  reducer: {
    counter: counterReducer,
    user: userReducer,
  },
});
export default store;

configureStore 自动帮你:

步骤 2:创建 Slice

// src/features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0,
    history: [],
  },
  reducers: {
    increment: (state) => {
      // Immer 允许直接修改 state
      state.value += 1;
      state.history.push(`+1 → ${state.value}`);
    },
    decrement: (state) => {
      state.value -= 1;
      state.history.push(`-1 → ${state.value}`);
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
      state.history.push(`+${action.payload} → ${state.value}`);
    },
    reset: (state) => {
      state.value = 0;
      state.history = [];
    },
  },
});
export const { increment, decrement, incrementByAmount, reset } = counterSlice.actions;
export default counterSlice.reducer;

createSlice 自动生成:

步骤 3:处理异步请求

// src/features/user/userSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
// 创建异步 thunk
export const fetchUser = createAsyncThunk(
  'user/fetchUser',
  async (userId, { rejectWithValue }) => {
    try {
      const response = await axios.get(`/api/users/${userId}`);
      return response.data;
    } catch (error) {
      return rejectWithValue(error.response.data);
    }
  }
);
const userSlice = createSlice({
  name: 'user',
  initialState: {
    data: null,
    loading: false,
    error: null,
  },
  reducers: {
    clearUser: (state) => {
      state.data = null;
      state.error = null;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchUser.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchUser.fulfilled, (state, action) => {
        state.loading = false;
        state.data = action.payload;
      })
      .addCase(fetchUser.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      });
  },
});
export const { clearUser } = userSlice.actions;
export default userSlice.reducer;

createAsyncThunk 自动生成三种状态:

步骤 4:React 组件中使用

// src/components/Counter.jsx
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount, reset } from '../features/counter/counterSlice';
function Counter() {
  const count = useSelector((state) => state.counter.value);
  const history = useSelector((state) => state.counter.history);
  const dispatch = useDispatch();
  return (
    <div className="counter">
      <h2>计数器:{count}</h2>
      <div className="buttons">
        <button onClick={() => dispatch(decrement())}>-</button>
        <button onClick={() => dispatch(increment())}>+</button>
        <button onClick={() => dispatch(incrementByAmount(5))}>+5</button>
        <button onClick={() => dispatch(reset())}>重置</button>
      </div>
      {history.length > 0 && (
        <div className="history">
          <h3>操作历史:</h3>
          <ul>
            {history.map((item, index) => (
              <li key={index}>{item}</li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
}
export default Counter;
// src/components/UserProfile.jsx
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchUser, clearUser } from '../features/user/userSlice';
function UserProfile({ userId }) {
  const dispatch = useDispatch();
  const { data, loading, error } = useSelector((state) => state.user);
  useEffect(() => {
    dispatch(fetchUser(userId));
  }, [userId, dispatch]);
  if (loading) return <div>加载中...</div>;
  if (error) return <div>错误:{error}</div>;
  if (!data) return null;
  return (
    <div className="user-profile">
      <h2>{data.name}</h2>
      <p>邮箱:{data.email}</p>
      <button onClick={() => dispatch(clearUser())}>清除</button>
    </div>
  );
}
export default UserProfile;

三、项目结构组织

src/
├── app/
│   └── store.js          # Store 配置
├── features/
│   ├── counter/
│   │   ├── counterSlice.js
│   │   └── Counter.jsx
│   └── user/
│       ├── userSlice.js
│       └── UserProfile.jsx
├── components/            # 通用组件
└── index.js              # 入口文件
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')).render(
  <Provider store={store}>
    <App />
  </Provider>
);

四、最佳实践

1. 使用 Typed Hooks(TypeScript 项目)

// src/app/hooks.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import type { RootState, AppDispatch } from './store';
// 在整个应用中使用这些 hooks,而非默认的 useDispatch/useSelector
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

2. Slice 文件组织

3. 避免的常见错误

错误做法正确做法
直接修改 state 外部只在 reducer 内修改
在 slice 中发异步请求使用 createAsyncThunk
过多全局状态局部状态用 useState
忽略 extraReducers正确处理异步状态

总结

Redux Toolkit 让 Redux 开发变得简单高效:

  1. configureStore - 一键配置 store
  2. createSlice - 自动生成 action + reducer
  3. createAsyncThunk - 优雅处理异步
  4. Immer 内置 - 直接修改 state 无副作用

选型建议:

到此这篇关于Redux Toolkit 实战小结的文章就介绍到这了,更多相关Redux Toolkit 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文