[React] React 中使用 Redux

安装依赖

file:[安装依赖包]
pnpm i @reduxjs/toolkit react-redux

同步操作

通过调用 createSlice 方法创建的 counterStore 对象包含了两个属性:actions 和 reducer。actions 对象包含了所有生成的 action creators,而 reducer 是一个可以直接传递给 Redux store 的 reducer 函数。

这样,我们可以在应用中使用 increment 和 decrement 这两个 action creators 来分发 action,从而改变 Redux store 中 counterStore 的状态。

file:[src/store/counter-store.js]
import { createSlice } from "@reduxjs/toolkit";

const counterStore = createSlice({
  name: "counterStore", // slice 的名称
  initialState: {
    count: 0, // 初始状态
  },
  reducers: {
    // 定义增加 count 的 reducer
    increment(state) {
      state.count++;
    },
    // 定义减少 count 的 reducer
    decrement(state) {
      state.count--;
    },
  },
});

// 导出 actions 和 reducer
export const { increment, decrement } = counterStore.actions;
export const counterReducer = counterStore.reducer;

通过将 counterReducer 添加到 store 的 reducer 中,我们可以在应用中使用 Redux store 来管理 counterStore 的状态。这样,当 dispatch 一个 action 时,Redux store 会根据 reducer 的逻辑来更新 counterStore 的状态,并触发应用中相关的 UI 更新。

file:[src/store/index.js]
import { configureStore } from "@reduxjs/toolkit";
import { counterReducer } from "./counter-store"; // 导入之前定义的 counterReducer

// 使用 configureStore 方法创建 Redux store
const store = configureStore({
  reducer: {
    counterReducer, // 将 counterReducer 添加到 store 的 reducer 中
  },
});

export default store; // 导出创建好的 Redux store

注入 store。

file:[src/index.js]
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import store from "./store";
import { Provider } from "react-redux";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

reportWebVitals();

使用 React Redux 提供的 useSelectoruseDispatch 钩子来连接 Redux store。

file:[src/App.js]
import "./App.css";
import { useSelector, useDispatch } from "react-redux";
import { decrement, increment } from "./store/counter-store"; // 导入 action creators

function App() {
  // 使用 useSelector 钩子从 Redux store 中获取 count 状态
  const count = useSelector((state) => state.counterReducer.count);
  // 使用 useDispatch 钩子获取 dispatch 函数
  const dispatch = useDispatch();

  return (
    <div className="App">
      {/* 点击按钮调用 dispatch 函数分发 decrement action */}
      <button onClick={() => dispatch(decrement())}>-</button>
      {/* 显示 count 状态 */}
      {count}
      {/* 点击按钮调用 dispatch 函数分发 increment action */}
      <button onClick={() => dispatch(increment())}>+</button>
    </div>
  );
}

export default App;

异步操作

fetchRecommends 是一个异步 action creator,用于获取推荐频道数据。它返回一个异步函数,接收 dispatch 参数,利用 axios 发起异步请求,获取推荐频道数据,并将数据通过 setRecommends action 更新到 Redux store 中的 recommends 状态中。

file:[src/store/recommendsStore.js]
import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";

const recommendsStore = createSlice({
  name: "recommendsStore", // slice 的名称
  initialState: {
    recommends: [], // 初始状态,推荐频道数组为空
  },
  reducers: {
    // 更新推荐频道的 reducer
    setRecommends(state, action) {
      state.recommends = action.payload;
    },
  },
});

// 导出 actions 和 reducer
export const { setRecommends } = recommendsStore.actions;
export const recommendsReducer = recommendsStore.reducer;

// 异步 action creator,用于获取推荐频道数据
export function fetchRecommends() {
  return async (dispatch) => {
    // 发起异步请求获取推荐频道数据
    const res = await axios.get("http://geek.itheima.net/v1_0/channels");
    // 将获取到的数据通过 setRecommends action 更新到 store 中
    dispatch(setRecommends(res.data.data.channels));
  };
}

组件中使用了 React Redux 提供的 useDispatchuseSelector 钩子来连接 Redux store,并利用 useEffect 钩子在组件挂载时触发异步 action creator 来获取推荐频道数据。

file:[src/App.js]
import { useEffect } from "react";
import { fetchRecommends } from "./store/recommendsStore"; // 导入异步 action creator
import { useDispatch, useSelector } from "react-redux";

function App() {
  const dispatch = useDispatch(); // 获取 dispatch 函数
  const { recommends } = useSelector((state) => state.recommendsReducer); // 获取 recommends 状态

  useEffect(() => {
    // 组件挂载时触发异步 action creator 获取推荐频道数据
    dispatch(fetchRecommends());
  }, [dispatch]); // 依赖 dispatch 函数

  return (
    <div>
      <ul>
        {/* 遍历推荐频道数据并展示 */}
        {recommends.map((channel) => (
          <li key={channel.id}>{channel.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;
posted @ 2024-03-31 23:58  Himmelbleu  阅读(8)  评论(0编辑  收藏  举报