react reducx的使用

安装依赖

在React项目中,需要安装@reduxjs/toolkitreact-redux两个包:

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

创建Redux相关文件

  1. 创建slice

    • 使用createSlice创建slice,它会自动生成action creator和reducer。例如:

      复制代码
      import { createSlice } from '@reduxjs/toolkit';
      
      const counterSlice = createSlice({
        name: 'counter',
        initialState: {
          count: 0
        },
        reducers: {
          increment(state) {
            state.count++;
          },
          decrement(state) {
            state.count--;
          },
          addToNum(state, action) {
            state.count += action.payload;
          }
        }
      });
      
      export const { increment, decrement, addToNum } = counterSlice.actions;
      export default counterSlice.reducer;
  2. 创建store

    • 使用configureStore创建store,它会自动配置中间件和Redux DevTools:

      复制代码
      import { configureStore } from '@reduxjs/toolkit';
      import counterReducer from './counterSlice';
      
      const store = configureStore({
        reducer: {
          counter: counterReducer
        }
      });
      
      export default store;

在React应用中使用Redux

  1. 提供store

    • 在React应用的顶层组件中,使用<Provider>组件将store提供给整个应用:

      复制代码
      import React from 'react';
      import ReactDOM from 'react-dom';
      import { Provider } from 'react-redux';
      import store from './store';
      import App from './App';
      
      ReactDOM.render(
        <Provider store={store}>
          <App />
        </Provider>,
        document.getElementById('root')
      );
  2. 在组件中使用Redux

    • 在React组件中,可以使用useSelectoruseDispatch两个Hooks来读取state和分发action

      复制代码
      import React from 'react';
      import { useSelector, useDispatch } from 'react-redux';
      import { increment, decrement, addToNum } from './counterSlice';
      
      function Counter() {
        const count = useSelector(state => state.counter.count);
        const dispatch = useDispatch();
      
        return (
          <div>
            <p>Count: {count}</p>
            <button onClick={() => dispatch(increment())}>Increment</button>
            <button onClick={() => dispatch(decrement())}>Decrement</button>
            <button onClick={() => dispatch(addToNum(20))}>Add 20</button>
          </div>
        );
      }
      
      export default Counter;

2. 创建异步Thunk

使用createAsyncThunk创建一个异步Thunk,它会自动生成pendingfulfilledrejected的action类型。例如,假设你有一个API接口https://jsonplaceholder.typicode.com/users,你想要获取用户数据并更新state:

复制代码
// src/thunks/userThunks.js
import { createAsyncThunk } from '@reduxjs/toolkit';

export const fetchUserById = createAsyncThunk(
  'users/fetchById',
  async (userId) => {
    const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
    if (!response.ok) {
      throw new Error('Failed to fetch user');
    }
    return response.json();
  }
);

3. 创建Slice

createSlice中处理异步Thunk的pendingfulfilledrejected状态。你可以使用extraReducers来监听这些状态并更新state:

复制代码
// src/slices/userSlice.js
import { createSlice } from '@reduxjs/toolkit';
import { fetchUserById } from '../thunks/userThunks';

const initialState = {
  user: null,
  status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
  error: null
};

const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchUserById.pending, (state) => {
        state.status = 'loading';
      })
      .addCase(fetchUserById.fulfilled, (state, action) => {
        state.status = 'succeeded';
        state.user = action.payload;
      })
      .addCase(fetchUserById.rejected, (state, action) => {
        state.status = 'failed';
        state.error = action.error.message;
      });
  }
});

export default userSlice.reducer;

4. 创建Store

store.js中配置store,引入你的slice和Thunk:

复制代码
// src/store.js
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './slices/userSlice';

export const store = configureStore({
  reducer: {
    user: userReducer
  }
});

5. 在React组件中使用

在React组件中,你可以使用useDispatch来触发异步Thunk,并使用useSelector来读取state:

复制代码
// src/components/UserComponent.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchUserById } from '../thunks/userThunks';

function UserComponent() {
  const dispatch = useDispatch();
  const { user, status, error } = useSelector((state) => state.user);

  const handleFetchUser = () => {
    dispatch(fetchUserById(1)); // 假设用户ID为1
  };

  return (
    <div>
      <button onClick={handleFetchUser}>Fetch User</button>
      {status === 'loading' && <p>Loading...</p>}
      {status === 'succeeded' && (
        <div>
          <h2>User Details</h2>
          <p>Name: {user.name}</p>
          <p>Email: {user.email}</p>
        </div>
      )}
      {status === 'failed' && <p>Error: {error}</p>}
    </div>
  );
}

export default UserComponent;

6. 提供Store

确保在顶层组件中使用<Provider>来提供store:

复制代码
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './store';
import App from './App';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

2.多个reducer时, 使用combineReducers组合reducer

store.js中,使用combineReducers将多个reducer组合成一个根reducer,然后传递给store。

复制代码
// src/store.js
import { configureStore, combineReducers } from '@reduxjs/toolkit';
import userReducer from './slices/userSlice';
import counterReducer from './slices/counterSlice';

const rootReducer = combineReducers({
  user: userReducer,
  counter: counterReducer
});

export const store = configureStore({
  reducer: rootReducer
});
相关推荐
han_7 分钟前
一篇看懂国内外主流大模型:GPT、Claude、Gemini、DeepSeek、通义千问有什么区别?
前端·人工智能·llm
一行代码一行诗++15 分钟前
注释是什么和注释该怎么写(C语言)
java·前端·javascript
涂兵兵_青石疏影22 分钟前
beginPath-vs-save详解
前端
泽_浪里白条34 分钟前
我在 Superset 6.x 做自定义图表 + Embedded SDK 集成的实战复盘(附踩坑清单)
前端·数据可视化
幽络源小助理1 小时前
小六壬排盘工具源码 自适应双端 纯原生HTML+JS
前端·javascript·html
Championship.23.242 小时前
Open Source Pipeline Skill深度解析:自动化开源贡献全流程
前端·javascript·html
Bigger2 小时前
🧠 前端岗位的"结构性调整":现象背后的冷思考
前端·程序员·ai编程
薯老板2 小时前
vue组件之间的通信
前端·vue.js
迪菲赫尔曼2 小时前
从 0 到 1 打造工业级推理控制台:UltraConsole(Ultralytics + FastAPI + React)开源啦!
前端·yolo·react.js·计算机视觉·开源·fastapi
万邦科技Lafite2 小时前
京东开放API接口:item_get返回参数指南
java·前端·javascript·api·电商开放平台