我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ReactQuery数据转换怎么实现

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

ReactQuery数据转换怎么实现

本文小编为大家详细介绍“ReactQuery数据转换怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“ReactQuery数据转换怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

数据转换

我们不得不面对这个问题-大部分的人并没有使用GraphQL。如果你使用了,那么恭喜你,因为你可以请求到你期望的数据格式。

如果你在使用REST风格的API,你就必须受限于后端返回的数据格式。所以在使用react-query的时候我们应该在什么地方通过什么方式来进行数据转换呢?

答案只有一个:看情况。

下面列举出四种进行数据转换的方式,以及他们的优缺点:

后端

这是我最喜欢的方式,如果你有决定权的话。如果后端返回的数据结构是你所期望的话,那么你就什么都不用做了。但是在很多场景这并不太现实,比如一些公共的REST API,特别是在企业级应用中。如果你可以让后端针对每一个具体的场景都有一个对应的接口,那么可以返回你期望的数据结构。

  • 优点:
    前端什么都不用做

  • 缺点:
    并不是所有情况下都能做到

查询函数中

查询函数是你传给useQuery的函数。他会返回一个Promise,最终返回的数据会被存在缓存中。但是这并不意味着你只能按照后端给你的数据结构来返回数据。你可以在返回之前进行数据转换:

const fetchTodos = async (): Promise<Todos> => {  const response = await axios.get('todos')  const data: Todos = response.data  return data.map((todo) => todo.name.toUpperCase())}export const useTodosQuery = () => useQuery(['todos'], fetchTodos)

之后你就可以在其他地方使用转换之后的数据,仿佛后端返回的数据就是这样的。你在其他地方都不会拿到不是大写的todo名字了。同时你也拿不到数据的原始结构了。如果你查看react-query-devtools,你会看到转换之后的结构。如果你查看网络请求,你可以看到原始的数据结构。这个可能会有点让人感到困惑,所以不要忘了你在代码里面处理了数据结构。

同时,在这里react-query并不会做什么优化。也就是说每一次fetch被执行的时候,你的转换逻辑都会被执行。如果转换逻辑很复杂,需要考虑一下其他转换方式。一些公司在前端会有一个公共的API层来抽象数据获取,所以你可能没办法在这个抽象层里面做你的数据转换。

  • 优点:
    和API调用绑定在一起,对上层无感知

  • 缺点:
    在每次数据请求的时候都会运行
    如果你有一个你无法修改的公共的API层,这个方式不太可行

  • 其他:
    存储在缓存中的是转换之后的数据结构,所以你没办法拿到原始的数据结构

render函数中

你可以自定义一个hook,那么你可以很方便的在这个hook里做数据转换:

const fetchTodos = async (): Promise<Todos> => {  const response = await axios.get('todos')  return response.data}export const useTodosQuery = () => {  const queryInfo = useQuery(['todos'], fetchTodos)  return {    ...queryInfo,    data: queryInfo.data?.map((todo) => todo.name.toUpperCase()),  }}

正如代码逻辑所示,数据转换不会在每次数据查询的时候运行,但是会在每次render的时候运行(即使这次render并没有触发数据请求)。这看起来这不是什么大问题,如果你在意的话,你可以通过useMemo来进行优化,同时尽可能只定义真正需要的依赖列表。queryInfo中的data是引用稳定的除非数据真的发生了变化,但是queryInfo就不是了。如果你把queryInfo作为你的依赖,那么转换逻辑就会在每次render的时候运行:

export const useTodosQuery = () => {  const queryInfo = useQuery(['todos'], fetchTodos)  return {    ...queryInfo,    // ???? don't do this - the useMemo does nothing at all here!    data: React.useMemo(      () => queryInfo.data?.map((todo) => todo.name.toUpperCase()),      [queryInfo]    ),    // ✅ correctly memoizes by queryInfo.data    data: React.useMemo(      () => queryInfo.data?.map((todo) => todo.name.toUpperCase()),      [queryInfo.data]    ),  }}

特别是当你在自定义hook中有一些额外的逻辑来协助进行数据转换的时候,这是一个很好的选择。需要注意的是data有可能是undefined,所以请使用可选链式访问来获取data中的数据。

  • 优点:
    可以通过useMemo进行优化

  • 缺点
    写法有一些晦涩
    data可能会是undefined

  • 其他
    确切的数据结构无法在devtool中展示

使用select配置

v3引入了内置的selector,可以用它来进行数据转换:

export const useTodosQuery = () =>  useQuery(['todos'], fetchTodos, {    select: (data) => data.map((todo) => todo.name.toUpperCase()),  })

selector只会在data存在的时候被调用,所以你不用担心undefiend的问题。像上面的selector会在每次render的时候被执行,因为函数表达式变化了(因为这是一个内联函数)。如果转换逻辑比较复杂,你可以使用useCallback来进行memoize,或者把他抽象到一个稳定的函数引用中:

const transformTodoNames = (data: Todos) =>  data.map((todo) => todo.name.toUpperCase())export const useTodosQuery = () =>  useQuery(['todos'], fetchTodos, {    // ✅ uses a stable function reference    select: transformTodoNames,  })export const useTodosQuery = () =>  useQuery(['todos'], fetchTodos, {    // ✅ memoizes with useCallback    select: React.useCallback(      (data: Todos) => data.map((todo) => todo.name.toUpperCase()),      []    ),  })

在未来,select配置也可以被用来订阅data中的部分数据。这使得这一数据转换实现方式变得特别。看看下面这个例子:

export const useTodosQuery = (select) =>  useQuery(['todos'], fetchTodos, { select })export const useTodosCount = () => useTodosQuery((data) => data.length)export const useTodo = (id) =>  useTodosQuery((data) => data.find((todo) => todo.id === id))

这里,我们创建了一个像useSelector一样的API,你可以传自定义selector到useTodosQuery中。这个自定义hook仍然可以像之前一样工作,如果你没有传select,会返回整个数据。
但是如果你传了selector,你就只会订阅selector返回的部分数据。这是很有用的,因为这意味着如果我们更新了一个todo的名字,只通过useTodosCount订阅了count的组件并不会重新渲染。count没有发生变化,所以react-query可以选择不通知这部分数据的订阅者(注意这里说得很容易,但是具体实现不完全跟这个描述一样,我会在第三部分渲染优化中聊一聊这部分内容)

  • 优点:
    最佳优化
    支持部分订阅

  • 其他:
    每个订阅者的数据可能都不一样

读到这里,这篇“ReactQuery数据转换怎么实现”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

ReactQuery数据转换怎么实现

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

ReactQuery数据转换怎么实现

本文小编为大家详细介绍“ReactQuery数据转换怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“ReactQuery数据转换怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。数据转换我们不得不面对
2023-07-04

ReactQuery系列之数据转换示例详解

这篇文章主要为大家介绍了ReactQuery系列之数据转换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

Python中怎么实现数据转换

今天就跟大家聊聊有关Python中怎么实现数据转换,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。import pyfme FME_GEOMETRY_TYPE={ 0:"FME_
2023-06-17

java怎么实现数据类型的转换

在Java中,可以使用类型转换操作符将一种数据类型转换成另一种数据类型。类型转换分为两种:隐式类型转换和显式类型转换。1. 隐式类型转换:当将一个小范围的数据类型转换为一个大范围的数据类型时,Java会自动进行类型转换。例如,将一个整数类型
2023-10-09

php数据类型自动转换怎么实现

这篇文章主要讲解了“php数据类型自动转换怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“php数据类型自动转换怎么实现”吧!1.强类型和弱类型PHP变量有两种类型:强类型和弱类型。强
2023-07-05

VB.NET如何实现数据转换

这篇文章给大家分享的是有关VB.NET如何实现数据转换的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。VB.NET数据转换的方法有很多种,要想熟练的掌握好这些实用技巧,就需要通过不断的实践去积累经验,来熟练掌握这一
2023-06-17

Java中怎么实现基本数据类型转换

这期内容当中小编将会给大家带来有关Java中怎么实现基本数据类型转换,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。自动类型转换自动类型转换是指:数字表示范围小的数据类型可以自动转换成范围大的数据类型。如:
2023-06-17

C#怎么实现数组元素的数据类型转换

这篇文章主要介绍“C#怎么实现数组元素的数据类型转换”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C#怎么实现数组元素的数据类型转换”文章能帮助大家解决问题。一、场景假设假设有一串字符串如下所示,字
2023-06-30

mysql 数据类型转换的实现

一、问题 有一张如下图所示的表,需要我们查出 result 值大于 reference_high值的数据然后我们写了下面的SQL查询语句SELECT i.result,i.reference_high FROM report_item i
2022-05-25

python数据处理之Pandas类型转换怎么实现

这篇文章主要介绍“python数据处理之Pandas类型转换怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“python数据处理之Pandas类型转换怎么实现”文章能帮助大家解决问题。转换为字
2023-06-30

winform数字日期转换怎么实现

要实现数字和日期之间的转换,可以使用DateTime.ParseExact和ToString方法来实现。首先,将数字转换为日期,可以使用DateTime.ParseExact方法。该方法需要传入两个参数,第一个参数是要转换的数字字符串,第
2023-10-23

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录