19 【RTK Query】

本文介绍了RTK Query在前端请求管理中的作用,包括简化数据加载、缓存管理和减少重复请求。RTK Query是Redux Toolkit的一部分,用于优化接口请求,提供自动缓存和数据管理功能。文章详细讲解了定义API Slice、配置Store、使用Query Hooks、处理参数、转换响应以及缓存机制,并通过实例展示了RTK Query在React中的应用。
摘要由CSDN通过智能技术生成

19 【RTK Query】

1.目前前端常见的发起 ajax 请求的方式

  • 1、使用原生的ajax请求
  • 2、使用jquery封装好的ajax请求
  • 3、使用fetch发起请求
  • 4、第三方的比如axios请求
  • 5、angular中自带的HttpClient

就目前前端框架开发中来说我们在开发vuereact的时候一般都是使用fetchaxios自己封装一层来与后端数据交互,至于angular肯定是用自带的HttpClient请求方式,但是依然存在几个致命的弱点,

  • 1、对当前请求数据不能缓存,
  • 2、一个页面上由多个组件组成,但是刚好有遇到复用相同组件的时候,那么就会发起多次ajax请求

📢 针对同一个接口发起多次请求的解决方法,目前常见的解决方案

  • 1、使用axios的取消发起请求,参考文档
  • 2、vue中还没看到比较好的方法
  • 3、在rect中可以借用类似react-query工具对请求包装一层
  • 4、对于angular中直接使用rxjs的操作符shareReplay

2.RTK Query 概述

RTK不仅帮助我们解决了state的问题,同时,它还为我们提供了RTK Query用来帮助我们处理数据加载的问题。RTK Query是一个强大的数据获取和缓存工具。在它的帮助下,Web应用中的加载变得十分简单,它使我们不再需要自己编写获取数据和缓存数据的逻辑。

rtk-queryredux-toolkit里面的一个分之,专门用来优化前端接口请求,目前也只支持在react中使用。

RTK Query 是一个强大的数据获取和缓存工具。它旨在简化在 Web 应用程序中加载数据的常见情况,无需自己手动编写数据获取和缓存逻辑

RTK Query 是一个包含在 Redux Toolkit 包中的可选插件,其功能构建在 Redux Toolkit 中的其他 API 之上。

Web应用中加载数据时需要处理的问题:

  1. 根据不同的加载状态显示不同UI组件
  2. 减少对相同数据重复发送请求
  3. 使用乐观更新,提升用户体验
  4. 在用户与UI交互时,管理缓存的生命周期

这些问题,RTKQ都可以帮助我们处理。首先,可以直接通过RTKQ向服务器发送请求加载数据,并且RTKQ会自动对数据进行缓存,避免重复发送不必要的请求。其次,RTKQ在发送请求时会根据请求不同的状态返回不同的值,我们可以通过这些值来监视请求发送的过程并随时中止。

我们将 createAsyncThunkcreateSlice 一起使用,在发出请求和管理加载状态方面仍然需要进行大量手动工作。我们必须创建异步 thunk,发出实际请求,从响应中提取相关字段,添加加载状态字段,在 extraReducers 中添加处理程序以处理 pending/fulfilled/rejected 情况,并实际编写正确的状态更新。

在过去的几年里,React 社区已经意识到 “数据获取和缓存” 实际上是一组不同于 “状态管理” 的关注点。虽然你可以使用 Redux 之类的状态管理库来缓存数据,但用例差异较大,因此值得使用专门为数据获取用例构建的工具。

RTK Query 在其 API 设计中添加了独特的方法:

  • 数据获取和缓存逻辑构建在 Redux Toolkit 的 createSlicecreateAsyncThunk API 之上
  • 由于 Redux Toolkit 与 UI 无关,因此 RTK Query 的功能可以与任何 UI 层一起使用
  • API 请求接口是提前定义的,包括如何从参数生成查询参数和转换响应以进行缓存
  • RTK Query 还可以生成封装整个数据获取过程的 React hooks ,为组件提供 dataisFetching 字段,并在组件挂载和卸载时管理缓存数据的生命周期
  • RTK Query 提供“缓存数据项生命周期函数”选项,支持在获取初始数据后通过 websocket 消息流式传输缓存更新等用例
  • 我们有从 OpenAPI 和 GraphQL 模式生成 API slice 代码的早期工作示例
  • 最后,RTK Query 完全用 TypeScript 编写,旨在提供出色的 TS 使用体验

📢 rtk-query的使用环境,必须是react版本大于 17,可以使用hooks的版本,因为使用rtk-query的查询都是hooks的方式,如果你项目简单redux都未使用到,本人不建议你用rtk-query,可能直接使用axios请求更加的简单方便。

3.基础开发流程

后面这些案例后端接口返回格式都是

{
    
    "code":200,
    "data":[]
}
  • 创建一个store文件夹
  • 创建一个index.ts做为主入口
  • 创建一个festures/api文件夹用来装所有的API Slice
  • 创建一个sudentApiSlice.js文件,并导出简单的加减方法

3.1 定义 API Slice

使用 RTK Query,管理缓存数据的逻辑被集中到每个应用程序的单个“API Slice”中。就像每个应用程序只有一个 Redux 存储一样,我们现在有一个Slice 用于 所有 我们的缓存数据。

我们将从定义一个新的 sudentApiSlice.js 文件开始。由于这不是特定于我们已经编写的任何其他“功能”,我们将添加一个新的 features/api/ 文件夹并将 sudentApiSlice.js 放在那里。让我们填写 API Slice 文件,然后分解里面的代码,看看它在做什么:

features/api/sudentApiSlice.js

// 从特定于 React 的入口点导入 RTK Query 方法
import {
    createApi, fetchBaseQuery } from '@reduxjs/toolkit/dist/query/react'
// 上面这个引入的会自动创建钩子
// import { createApi } from '@reduxjs/toolkit/query'

// 定义我们的单个 API Slice 对象
//createApi() 用来创建RTKQ中的API对象
// RTKQ的所有功能都需要通过该对象来进行
// createApi() 需要一个对象作为参数
export const sudentApiSlice = createApi({
   
  reducerPath: 'studentApi', // Api的标识,不能和其他的Api或reducer重复
  // 指定查询的基础信息,发送请求使用的工具
  baseQuery: fetchBaseQuery({
   
    // 我们所有的请求都有以 “/api 开头的 URL
    baseUrl: 'http://localhost:8080/api',
  }),
  // “endpoints” 代表对该服务器的操作和请求
  endpoints: builder => ({
   
    // `getStudents` endpoint 是一个返回数据的 “Query” 操作
    getStudents: builder.query({
   
      // 请求的 URL 是“/api/all/student”
      query: () => '/all/student',
    }),
  }),
})

// Api对象创建后,对象中会根据各种方法自动的生成对应的钩子函数
// 通过这些钩子函数,可以来向服务器发送请求
// 钩子函数的命名规则 getStudents --> useGetStudentsQuery
export const {
    useGetStudentsQuery } = sudentApiSlice

上例是一个比较简单的Api对象的例子,我们来分析一下,首先我们需要调用createApi()来创建Api对象。这个方法在RTK中存在两个版本,一个位于@reduxjs/toolkit/dist/query下,一个位于@reduxjs/toolkit/dist/query/react下。react目录下的版本会自动生成一个钩子,方便我们使用Api。如果不要钩子,可以引入query下的版本,当然我不建议你这么做。

createApi()需要一个配置对象作为参数,配置对象中的属性繁多,我们暂时介绍案例中用到的属性:

reducerPath

用来设置reducer的唯一标识,主要用来在创建store时指定action的type属性,如果不指定默认为api。

baseQuery

用来设置发送请求的工具,就是你是用什么发请求,RTKQ为我们提供了fetchBaseQuery作为查询工具,它对fetch进行了简单的封装,很方便,如果你不喜欢可以改用其他工具,这里暂时不做讨论。

fetchBaseQuery

简单封装过的fetch调用后会返回一个封装后的工具函数。需要一个配置对象作为参数,baseUrl表示Api请求的基本路径,指定后请求将会以该路径为基本路径。配置对象中其他属性暂不讨论。

endpoints

Api对象封装了一类功能,比如学生的增删改查,我们会统一封装到一个对象中。一类功能中的每一个具体功能我们可以称它是一个端点。endpoints用来对请求中的端点进行配置。

endpoints是一个回调函数,可以用普通方法的形式指定,也可以用箭头函数。回调函数中会收到一个build对象,使用build对象对点进行映射。回调函数的返回值是一个对象,Api对象中的所有端点都要在该对象中进行配置。

对象中属性名就是要实现的功能名,比如获取所有学生可以命名为getStudents,根据id获取学生可以命名为getStudentById。属性值要通过build对象创建,分两种情况:

查询:build.query({})

增删改:build.mutation({})

例如:

getStudents: builder.query({
   
  // 请求的 URL 是“/api/all/student”
  query: () => '/all/student',
}),

先说query,query也需要一个配置对象作为参数。配置对象里同样有n多个属性,现在直说一个,query方法。注意不要搞混两个query,一个是build的query方法,一个是query方法配置对象中的属性,这个方法需要返回一个子路径,这个子路径将会和baseUrl拼接为一个完整的请求路径。比如:getStudets的最终请求地址是:

http://localhost:8080/api + /all/student = http://localhost:8080/api/all/student

可算是介绍完了,但是注意了这个只是最基本的配置。RTKQ功能非常强大,但是配置也比较麻烦。不过,熟了就好了。

上例中,我们创建一个Api对象studentApi,并且在对象中定义了一个getStudents方法用来查询所有的学生信息。如果我们使用react下的createApi,则其创建的Api对象中会自动生成钩子函数,钩子函数名字为useXxxQuery或useXxxMutation,中间的Xxx就是方法名,查询方法的后缀为Query,修改方法的后缀为Mutation。所以上例中,Api对象中会自动生成一个名为useGetStudentsQuery的钩子,我们可以获取并将钩子向外部暴露。

export const {
   useGetStudentsQuery} = studentApi;

3.2 配置 Store

我们现在需要将 API Slice 连接到我们的 Redux 存储。我们可以修改现有的 store.js 文件,将 API slice 的 cache reducer 添加到状态中。此外,API slice 会生成需要添加到 store 的自定义 middleware。这个 middleware 必须 被添加——它管理缓存的生命周期和控制是否过期。

store/index.js

import {
    configureStore } from '@reduxjs/toolkit'
import {
    sudentApiSlice } from './features/api/sudentApiSlice'

// configureStore创建一个redux数据
const store = configureStore({
   
  
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DSelegent

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值