在React项目中实现Redux的完整指南

下面我将展示如何在React项目中完整实现Redux状态管理,包括代码结构、配置和实例组件。

1. 项目结构

bash 复制代码
src/
├── app/
│   ├── store.js          # Redux store配置
├── features/
│   ├── counter/          # 功能模块
│   │   ├── counterSlice.js # Redux slice
│   │   └── Counter.js    # 关联组件
├── index.js              # 应用入口
└── App.js                # 根组件

2. 安装依赖

首先确保安装了必要的依赖:

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

3. 完整代码实现

3.1 创建Redux Store (app/store.js)

javascript 复制代码
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
 
export const store = configureStore({
  reducer: {
    counter: counterReducer,
    // 可以添加更多reducer
  },
  // 可选:添加Redux中间件
  middleware: (getDefaultMiddleware) => getDefaultMiddleware(),
  // 可选:启用Redux DevTools扩展
  devTools: process.env.NODE_ENV !== 'production',
});

3.2 创建Slice (features/counter/counterSlice.js)

javascript 复制代码
import { createSlice } from '@reduxjs/toolkit';
 
const initialState = {
  value: 0,
  status: 'idle',
};
 
export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
    setStatus: (state, action) => {
      state.status = action.payload;
    },
  },
  // 可选:处理异步逻辑的extraReducers
  extraReducers: (builder) => {
    // 可以在这里添加对异步thunk的响应
  },
});
 
// 导出actions
export const { increment, decrement, incrementByAmount, setStatus } = counterSlice.actions;
 
// 导出reducer
export default counterSlice.reducer;
 
// 可选:创建selector函数
export const selectCount = (state) => state.counter.value;
export const selectStatus = (state) => state.counter.status;

3.3 创建关联组件 (features/counter/Counter.js)

javascript 复制代码
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import {
  selectCount,
  selectStatus,
  increment,
  decrement,
  incrementByAmount,
  setStatus,
} from './counterSlice';
 
export function Counter() {
  const count = useSelector(selectCount);
  const status = useSelector(selectStatus);
  const dispatch = useDispatch();
  const [incrementAmount, setIncrementAmount] = useState('2');
 
  return (
    <div>
      <div>
        <button
          aria-label="Increment value"
          onClick={() => dispatch(increment())}
        >
          +
        </button>
        <span>{count}</span>
        <button
          aria-label="Decrement value"
          onClick={() => dispatch(decrement())}
        >
          -
        </button>
      </div>
      <div>
        <input
          value={incrementAmount}
          onChange={(e) => setIncrementAmount(e.target.value)}
          type="number"
        />
        <button
          onClick={() =>
            dispatch(incrementByAmount(Number(incrementAmount) || 0))
          }
        >
          Add Amount
        </button>
      </div>
      <div>
        <button onClick={() => dispatch(setStatus('loading'))}>
          Set Status to Loading
        </button>
        <div>Current Status: {status}</div>
      </div>
    </div>
  );
}

3.4 配置应用入口 (index.js)

javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import App from './App';
import { store } from './app/store';
import './index.css';
 
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

3.5 根组件 (App.js)

javascript 复制代码
import React from 'react';
import { Counter } from './features/counter/Counter';
 
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <h1>Redux Toolkit Demo</h1>
      </header>
      <main>
        <Counter />
      </main>
    </div>
  );
}
 
export default App;

4. 高级用法:异步逻辑

如果需要处理异步操作(如API调用),可以使用Redux Toolkit的createAsyncThunk

4.1 修改Slice添加异步逻辑

javascript 复制代码
// 在counterSlice.js中添加
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
 
// 创建异步thunk
export const incrementAsync = createAsyncThunk(
  'counter/fetchCount',
  async (amount) => {
    // 这里可以是API调用
    const response = await new Promise((resolve) =>
      setTimeout(() => resolve({ data: amount }), 500)
    );
    return response.data;
  }
);
 
// 然后在slice中处理异步状态
const counterSlice = createSlice({
  // ...其他配置保持不变
  extraReducers: (builder) => {
    builder
      .addCase(incrementAsync.pending, (state) => {
        state.status = 'loading';
      })
      .addCase(incrementAsync.fulfilled, (state, action) => {
        state.status = 'idle';
        state.value += action.payload;
      })
      .addCase(incrementAsync.rejected, (state) => {
        state.status = 'failed';
      });
  },
});

4.2 在组件中使用

javascript 复制代码
// 在Counter组件中添加
import { incrementAsync } from './counterSlice';
 
// 在组件函数中添加
const dispatch = useDispatch();
 
// 然后可以在按钮点击时使用
<button
  onClick={() => dispatch(incrementAsync(Number(incrementAmount) || 0))}
>
相关推荐
程序员海军17 小时前
2025年上半年前端技术圈生态总结分享
前端·vue.js·react.js
光头程序员18 小时前
vite_react 插件 find_code 最终版本
前端·javascript·react.js
_Kayo_20 小时前
React 学习笔记4 Diffing/脚手架
笔记·学习·react.js
山雀~20 小时前
React实现列表拖拽排序
前端·react.js·前端框架
前端世界20 小时前
前端路由切换不再白屏:React/Vue 实战优化全攻略(含可运行 Demo)
前端·vue.js·react.js
Java陈序员21 小时前
GitHub 星标太多管不过来?这款 AI 工具帮你一键整理、智能搜索!
react.js·openai·vite
日月晨曦21 小时前
React 在线 playground 实现指南:让代码在浏览器里「原地爆炸」的黑科技
前端·react.js
GISBox21 小时前
GISBox矢量服务使用指南:从数据导入到服务发布
react.js·json·gis
江城开朗的豌豆1 天前
Redux 到底香不香?手把手教你状态管理与更新!
前端·javascript·react.js
江城开朗的豌豆1 天前
React 性能优化必杀技:让你的应用飞起来!
前端·javascript·react.js