前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何提高redux开发效率?当然是redux-tookit啦!

如何提高redux开发效率?当然是redux-tookit啦!

作者头像
程序员王天
发布2023-10-18 19:18:59
2250
发布2023-10-18 19:18:59
举报

# 前言

使用 react-redux 的朋友都经历过这种痛苦吧? 定义一个 store 仓库,首先创建各种文件,比如 reducer、action、store...,然后 将 redux 和 react 连接使用。整个流程繁琐,写起来代码冗余。 react-redux 创建仓库,文件目录如下:

image.png
image.png

好怀念使用 vuex 创建写仓库的日子....... 直到有一天我发现了 redux-toolkit ,原来 redux 还能这样写呀!

# 什么是 redux-toolkit

redux-toolkit 是官方推荐的编写 redux 逻辑的方法,简化了 redux 的配置过程,无需再创建 actions、reducer 的,更大程度方便使用 redux 仓库

# 基本使用

redux-toolkit 的使用步骤,可分为如下 5 步

  • 1、安装 redex-toolkit
  • 2、创建 slices
  • 3、创建 store
  • 4、将 Redux 连接到 React 应用(provide)
  • 5、在 React 组件中使用(useSelector、useDispath)

# 环境配置

vscode React Redux Toolkit RTK Quer 安装 npm

代码语言:javascript
复制
npm i redux react-redux @reactjs/toolkit

# 创建切片 slices

一个切片是一个包含 reducer 函数和 action creator 的对象。它定义了一部分状态和与该状态相关的操作。

代码语言:javascript
复制
// sliceTbale.js

import { createSlice } from "@reduxjs/toolkit";

const moviesSlice = createSlice({
  name: "movies",
  // c初始化状态
  initialState: {
    currentData: [], //
    tableData: [],
  },
  reducers: {
    delete_table: (state, { payload }) => {
      // 通过筛选实现删除
      state.currentTable = state.currentTable.filter((item: { id: any }) => {
        return item.id !== payload.id;
      });
      state.table = state.currentTable;
      message.success("删除成功");
    },
  },
});

export const { addMovie } = moviesSlice.actions; // 导出 action creator
export default moviesSlice.reducer; // 导出 reducer

# 创建仓库-store

我们使用 configureStore 函数来创建 Redux Store,并使用刚刚创建的 reducer 将切片与 Store 关联起来。

代码语言:javascript
复制
// 创建store仓库
import { configureStore } from "@reduxjs/toolkit";
import initTable from "./module/table";

const reduxStore = configureStore({
  reducer: {
    // xxx: xxx,
    table: initTable,
  },
});

export default reduxStore;

# redux 链接 react

完成以上步骤,redux 配置 ok 啦,如何让整个项目中应用 redux 呢? 使用Provider包裹 React 顶层组件,将 Redux store 对象传递给组件树中的所有组件,使得 Redux 的状态管理能够在整个应用程序中生效。 打开项目的入口文件 index.tsx,代码如下:

代码语言:javascript
复制
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import RouterConfig from "./router/routerConfig";
import RouterView from "./router/routerView";
import "nprogress/nprogress.css"; // 样式
import { Provider } from "react-redux";
import reduxStore from "./store";

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <React.StrictMode>
    <Provider store={reduxStore}>
      <RouterView config={RouterConfig}></RouterView>
    </Provider>
  </React.StrictMode>
);

# 组件中使用 redux

使用状态和操作:在组件中,可以使用 useSelector 和 useDispatch 钩子来访问状态和触发 action。

代码语言:javascript
复制
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";

interface IndexProps {}

const Index: React.FC<IndexProps> = (props) => {
  //  获取redux仓库数据
  const tableState = useSelector((state: any) => state.table);
  // 创建redux 派发器
  const Dispath = useDispatch();
  console.log("table仓库数据", tableState);
  return <>{tableState.currentData.length}</>;
};

export default Index;

# 进阶使用

redux 中如何执行异步呢? createAsyncThunk 创建异步操作, 通常用于发出异步请求。 createAsyncThunk 创建一个异步 action,方法触发的时候会有三种状态:

  • pending(进行中)
  • fulfilled(成功)
  • rejected(失败)
代码语言:javascript
复制
export const getMovieData: any = createAsyncThunk(
  "sliceTable/getMovie",
  async () => {
    const res = await getMovieListApi();
    return res;
  }
);

# 完整示例

代码语言:javascript
复制
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { getMovieListApi } from "../../API/home";
import { message } from "antd";
// // createAsyncThunk 创建异步操作, 通常用于发出异步请求。
// createAsyncThunk 创建一个异步action,方法触发的时候会有三种状态:
// pending(进行中)、fulfilled(成功)、rejected(失败)
export const getMovieData: any = createAsyncThunk(
  "sliceTable/getMovie",
  async () => {
    const res = await getMovieListApi();
    return res;
  }
);

const sliceName = createSlice({
  name: "sliceTable",
  initialState: {
    table: [],
    currentTable: [],
  },
  reducers: {
    initTable: (state, { payload }) => {
      // console.log('初始化sliceTable数据')
    },
    delete_table: (state, { payload }) => {
      // 通过筛选实现删除
      state.currentTable = state.currentTable.filter((item: { id: any }) => {
        return item.id !== payload.id;
      });
      state.table = state.currentTable;
      message.success("删除成功");
    },
    serach_table: (state, { payload }) => {
      // 通过筛选实现删除
      console.log("payload", payload);
      state.currentTable = state.table.filter((item: { name: string }) => {
        return item.name.includes(payload);
      });
    },
  },
  // 让 slice 处理在别处定义的 actions, // 包括由 createAsyncThunk 或其他slice生成的actions
  extraReducers: (builder) =>
    builder
      .addCase(getMovieData.pending, (state, { payload }) => {
        // state.loading = true
        console.log("异步请求 中");
      })
      .addCase(getMovieData.fulfilled, (state, { payload }) => {
        // state.loading = false
        console.log("拿到异步数据");
        state.table = payload.data.data.list;
        state.currentTable = payload.data.data.list;
      })
      .addCase(getMovieData.rejected, (state, { payload }) => {
        // state.loading = false
        // state.error = payload
        console.log("异步操作错误");
      }),
});

export const { initTable, delete_table, serach_table } = sliceName.actions;
export default sliceName.reducer;

extraReducers // extraReducers 字段让 slice 处理在别处定义的 actions, // 包括由 createAsyncg 或其他 slice 生成的 actions。

# 使用 connect 函数将 store 内的数据映射到组件 props 内

代码语言:javascript
复制
import React, { PureComponent } from "react";
import { connect } from "react-redux";
import { addNamesAction } from "./store/features/names";
export class Profile extends PureComponent {
  addNames(nameValue) {
    // console.log(nameValue)
    this.props.addNamesHandler(nameValue);
  }
  render() {
    const { names } = this.props;
    return (
      <div>
        <h2>Profile names: {names}</h2>
        <button onClick={(e) => this.addNames(", lzumiShinichi")}>
          addNames
        </button>
        <button onClick={(e) => this.addNames(", 大吉")}>addNames</button>
        <button onClick={(e) => this.addNames(", OkabeRintaro")}>
          addNames
        </button>
      </div>
    );
  }
}
const mapStateToProps = (state) => {
  return {
    names: state.names.names,
  };
};
const mapDispatchToProps = (dispatch) => ({
  addNamesHandler(namesValue) {
    dispatch(addNamesAction(namesValue));
  },
});
export default connect(mapStateToProps, mapDispatchToProps)(Profile);

参考 https://www.cnblogs.com/chccee/p/17145403.htmlopen in new window https://juejin.cn/post/7101688098781659172?searchId=20230919111823C8EB8D22FECCCE8115FC#heading-9open in new window https://juejin.cn/post/7105000617596157983?searchId=20230919111823C8EB8D22FECCCE8115FC#heading-21open in new window

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023年9月30日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 前言
  • # 什么是 redux-toolkit
  • # 基本使用
    • # 环境配置
      • # 创建切片 slices
        • # 创建仓库-store
          • # redux 链接 react
            • # 组件中使用 redux
            • # 进阶使用
            • # 完整示例
              • # 使用 connect 函数将 store 内的数据映射到组件 props 内
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档