• 详细介绍 React 中如何使用 redux


    在使用之前要先了解它的配套插件:

    在React中使用redux,官方要求安装其他插件 Redux Toolkit 和 react-redux

    1. Redux Toolkit:它是一个官方推荐的工具集,旨在简化 Redux 的使用和管理。Redux Toolkit 提供了一些提高开发效率的工具和功能,如 createSlice 和 configureStore,使得编写和组织 Redux 代码更加简单。使用 Redux Toolkit,您可以更快地编写 Redux 代码,同时还能获得一些性能优化和开发便利。

      安装 Redux Toolkit:

    npm install @reduxjs/toolkit

    1. react-redux:它是 Redux 官方提供的与 React 集成的库。它提供了 Provider 组件来将 Redux store 注入到整个 React 应用中,以及 useDispatch 和 useSelector 这些方便的钩子函数,用于在 React 组件中使用 Redux 的 dispatch 和选择器功能。

      安装 react-redux:

    npm install react-redux

    安装这两个插件后,您就可以在 React 应用中使用 Redux 并使用 Redux Toolkit 进行更简洁、高效的编码,同时通过 react-redux 方便地与 React 进行集成。

    创建一个新的react 文件,且安装了两个插件后,调整目录结构

    image.png

    开始使用:

    第一步:初始化 state,定义修改状态的方法,解构出来 actionCreater函数,获取 reducer

    reducer 用于定义如何更新应用的状态。它接收两个参数:当前的状态(state)和即将执行的 action,并返回一个新的状态。

    counterStore.js

    import { createSlice } from "@reduxjs/toolkit";
    
    const counterStore = createSlice({
      name: "counter",
      
      // 初始化 state
      initialState: {
        count: 0,
      },
      
      // 修改状态的方法 同步方法,可以直接修改值
      reducers: {
        addCount(state) {
          state.count++;
        },
        decreaseCount(state) {
          state.count--;
        },
      },
    });
    
    // 解构出来 actionCreater函数
    const { addCount, decreaseCount } = counterStore.actions;
    // 获取 reducer
    const reducer = counterStore.reducer;
    // 按需导出
    export { addCount, decreaseCount };
    // 默认导出
    export default reducer;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    第二步:在出口文件中导出 redux

    src\store\index.js

    // 出口文件
    import { configureStore } from "@reduxjs/toolkit";
    // 导入子模块
    import counterStore from "./modules/counterStore";
    
    const store = configureStore({
      reducer: {
        counter: counterStore,
      },
    });
    
    // 导出
    export default store;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    第三步:配置redux 中的数据全局可用

    src\index.js

    import React from "react";
    import ReactDOM from "react-dom/client";
    import "./index.css";
    import App from "./App";
    import reportWebVitals from "./reportWebVitals";
    // Redux
    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();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    第四步:使用

    useDispatch:它简化了在函数组件中使用 dispatch 函数的过程,无需手动从 store 中获取 dispatch 函数。

    useSelector:它允许组件从 Redux store 中选择(select)所需的状态。通过它可以订阅 Redux store 的状态,以便在组件中获取所需的数据。

    App.js

    import "./App.css";
    import { useDispatch, useSelector } from "react-redux";
    // 获取
    import { addCount, decreaseCount } from "./store/modules/counterStore";
    
    function App() {
      // 得到 Redux 中的数据
      const { count } = useSelector((state) => state.counter);
      // 处理数据的函数
      const dispatch = useDispatch();
      return (
        <div className="App">
          <button onClick={() => dispatch(addCount())}>+</button>
          <p>{count}</p>
          <button onClick={() => dispatch(decreaseCount())}>-</button>
        </div>
      );
    }
    
    export default App;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    携带参数

     // 接收传参
        addTonum(state, action) {
          // action.payload 可以获取到传入的参数
          state.count = action.payload;
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    import { createSlice } from "@reduxjs/toolkit";
    
    const counterStore = createSlice({
      name: "counter",
      // 初始化 state
      initialState: {
        count: 0,
      },
      // 修改状态的方法 同步方法,可以直接修改值
      reducers: {
        addCount(state) {
          state.count++;
        },
        decreaseCount(state) {
          state.count--;
        },
        // 接收传参
        addTonum(state, action) {
          // action.payload 可以获取到传入的参数
          state.count = action.payload;
        },
      },
    });
    
    // 解构出来 actionCreater函数
    const { addCount, decreaseCount, addTonum } = counterStore.actions;
    // 获取 reducer
    // 用于定义如何更新应用的状态。它接收两个参数:当前的状态(state)和即将执行的 action,并返回一个新的状态。
    const reducer = counterStore.reducer;
    
    // 按需导出
    export { addCount, decreaseCount, addTonum };
    // 默认导出
    export default reducer;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    App.js

          <button onClick={() => dispatch(addTonum(10))}>+10</button>
          <button onClick={() => dispatch(addTonum(20))}>+20</button>
    
    • 1
    • 2

    异步请求部分

    异步封装的实现

    1.创建store的写法保持不变,配置好同步修改状态的方法

    2.单独封装一个函数,在函数内部return一个新函数,在新函数中

    2.1封装异步请求获取数据

    2.2调用同步actionCreater传入异步数据生成一个action对象,并使用dispatch提交

    3.组件中dispatch的写法保持不变

    src\store\modules\channelStore.js

    // 异步封装的实现
    import { createSlice } from "@reduxjs/toolkit";
    import axios from "axios";
    
    const channelStore = createSlice({
      name: "channel",
      
      // 初始值
      initialState: {
        channelList: [],
      },
      reducers: {
        setChannels(state, action) {
          state.channelList = action.payload;
        },
      },
    });
    
      
    // 异步请求部分
    // http://geek.itheima.net/v1_0/channels
    const { setChannels } = channelStore.actions;
    
    const fetchChannlList = () => {
      return async (dispatch) => {
        const res = await axios.get("http://geek.itheima.net/v1_0/channels");
        dispatch(setChannels(res.data.data.channels));
      };
    };
    
    export { fetchChannlList };
    
    const reducer = channelStore.reducer;
    export default reducer;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    出口文件

    src\store\index.js

    // 出口文件
    import { configureStore } from "@reduxjs/toolkit";
    // 导入子模块
    import counterStore from "./modules/counterStore";
    import channelStore from "./modules/channelStore";
    
    const store = configureStore({
      reducer: {
        counter: counterStore,
        channel: channelStore,
      },
    });
    
    // 导出
    export default store;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    使用

    App.js

    import "./App.css";
    import { useEffect } from "react";
    
    import { useDispatch, useSelector } from "react-redux";
    // 获取
    import {
      addCount,
      decreaseCount,
      addTonum,
    } from "./store/modules/counterStore";
    import { fetchChannlList } from "./store/modules/channelStore";
    
    function App() {
      // 得到 Redux 中的数据
      const { count } = useSelector((state) => state.counter);
      const { channelList } = useSelector((state) => state.channel);
    
      // 处理数据的函数
      const dispatch = useDispatch();
      // 挂载渲染
      useEffect(() => {
        dispatch(fetchChannlList());
      }, [dispatch]);
      return (
        <div className="App">
          <button onClick={() => dispatch(addCount())}>+</button>
          <p>{count}</p>
          <button onClick={() => dispatch(decreaseCount())}>-</button>
          <hr />
          {/* redux 传入参数 */}
          <button onClick={() => dispatch(addTonum(10))}>+10</button>
          <button onClick={() => dispatch(addTonum(20))}>+20</button>
          <hr />
          {/* 异步 */}
          <ul>
            {channelList.map((item) => (
              <li key={item.id}>{item.name}</li>
            ))}
          </ul>
        </div>
      );
    }
    
    export default App;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    浏览器插件,管理 redux

    Redux DevTools

  • 相关阅读:
    阿里云混合云密码应用分析
    Java面试之Redis篇(offer 拿来吧你)
    前端JavaScript中异步的终极解决方案:async/await
    推荐系统[八]算法实践总结V2:排序学习框架(特征提取标签获取方式)以及京东推荐算法精排技术实战
    git的使用场景
    Rust介绍与开发环境搭建
    新建并配置本地Git仓库的远程仓库--GitHub、推送本地仓库到GitHub。
    三七互娱,oppo,快手25届暑期实习内推
    【c++智能指针】
    安装配置Redis
  • 原文地址:https://blog.csdn.net/wbskb/article/details/131998390