iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >React之如何在Suspense中优雅地请求数据
  • 413
分享到

React之如何在Suspense中优雅地请求数据

在Suspense中请求数据ReactSuspenseSuspense请求数据 2023-05-17 14:05:40 413人浏览 泡泡鱼
摘要

目录什么是 Sunpense懒加载挂起懒加载组件的加载过程对需要请求数据的组件使用 SuspenseReact-cache自己写一个加工函数请求数据的时机结论什么是 Sunpense

什么是 Sunpense

Suspense 是 React 中的一个组件,直译过来有悬挂的意思,能够将其包裹的异步组件挂起,直到组件加载完成后再渲染

懒加载

在 React 组件挂载的过程中,一般是等所有的组件都加载好后一起挂载到 Dom 上, 如果出现了较大的组件,就会拖慢网页整体的加载速度,特别是在 SPA 上会出现长时间的白屏,影响用户体验

于是,React 提供了lazy api,用于延迟加载某个组件,这样就不会拖慢其他组件的加载速度

给 React 上的 lazy 方法传入一个返回 Promise 或类 Promise 对象的函数,即可实现对 Promise 的结果的懒加载

恰好,ES 中的动态引入import()就会返回一个 Promise,因此我们可将其写成匿名函数的返回值,并作为参数传给lazy,下面代码就对组件进行了懒加载

// 对Component进javascript行懒加载
const LazyComponent = React.lazy(() => import("./Component"));

挂起

但是通过lazy得出的组件直接使用的话会在加载时报错,还需要在外面包裹一层 Suspense 组件才能够正常使用

// 懒加的载子组件
const SubComponent = React.lazy(() => import("./SubComponent"));

// 用Suspense包裹的组件会被挂起,加载完成后再挂载
function MainComponent() {
	return <Suspense fallback={<div>Loading......</div>}>
        <SubComponent>
    </Suspense>;
}

渲染时,React 会先将 Suspense 的 fallback 中的内容挂载,并将子组件挂起,等待加载完成后就挂载,并将 fallback 卸载 例如上面的代码,会在 SubComponent 加载时显示 Loading......,等待 Subcomponent 加载完成后显示子组件内容

懒加载组件的加载过程

为啥直接使用会懒加载的组件报错呢?我们输出一下lazy返回的对象看看:

原来这个对象并不是我们熟悉的组件,而是拥有状态(status)和结果(result)的高阶对象,直接使用当然会报错啦

那么问题来了,React 为什么要返回这个对象而不是返回一个普通的组件呢?

这是为了通知 Suspense 组件!

简单地说,Suspense 组件会尝试渲染子组件,假如子组件未加载完成,则会转而渲染 fallback 里的内容

那么 Suspense 又是如何判断子组件是否加载完成的呢?对了,就是通过捕获子组件异常!

子组件有三种状态:

  • 加载中,抛出加载中的 Promise
  • 加载完成,正常返回结果
  • 加载异常,抛出错误

Suspense 会尝试加载子组件,并通componentDidCatch过对抛出的异常进行捕获,大概加载流程为:

这样,通过对未加载完成的子组件不断尝试加载,就能够实现“挂起”这一过程

对需要请求数据的组件使用 Suspense

现在我们知道,需要将子组件加载的状态通知 Suspense 才能够实等待 ajax 请求后再加载组件的效果,所以普通使用 ajax 发起请求是无法做到的

react-cache

react-cache 是 React 官方的处理数据副作用方案,里面提供了一个方法unstable_createResource,用于创建一个类似懒加载组件的对象

你可以访问这个对象上的read方法,若访问的数据不存在,则动态加载,并抛出 Promise,若数据存在,则正常返回数据。听起来是不是和懒加载很像?

import getURL from "./api"; //一个封装的请求,返回一个Promise
import { unstable_createResource } from "react-cache";

// 类似import(),传入一个返回值为PRomise的函数,生成一个拥有状态的对象
const myData = unstable_createResource(() => {
	getURL();
});
// 在子组件中使用
function SubComponent() {
	const data = myData.read();
	return <div>{data}</div>;
}

这样,父组件中包裹子组件的 Suspense 就能像检测懒加载组件一样检测子组件数据加载的状态,从而展示 fallback 或子组件了

但是,react-cache 其实是一种数据缓存方案,使用 LRU(当缓存空间满时,优先清理最近最少使用的数据)策略缓存数据,能够根据不同的参数缓存请求的结果,并供组件调用,如下

import getURL from "./api";
import { unstable_createResource } from "react-cache";

const myData = unstable_createResource(
	(param1, param2) => {
		getURL(param1, param2);
	},
	(param1, param2) => param1 + param2
);

unstable_createResource接受了两个参数

  • 第一个是产生 Promise 的函数,可以将参数传入匿名函数后再传入请求数据的函数(有点套娃,但是这样传参方便了函数内部复用请求)
  • 第二个参数是个哈希函数,作用是接受与前面函数同样的参数,然后生成一串识别码给函数本身查询数据是否存在(缓存)

这样,使用时就能read方法传递不同的参数,对于缓存一些高频使用的接口的数据非常有用

如果你只是想初始化时请求、不想使用缓存,或者单纯的不想引入更多库,那么可以手写一个能够通知 Suspense的函数

自己写一个加工函数

从上面两个例子可以知道,要通知 Suspense 函数,则必须要根据 Promise 状态进行不同的操作

为了简化,我们的加工函数就不自己创建 Promise 了,而是在外面创建后对 Promise 进行加工

// 创建函数,接受一个promise
function wrapPromise(promise) {
	let status = 0;
	let result;
	// 调用promise,并在回调中更改加工函数中的状态
	const callPromise = promise.then(
		(res) => {
			status = 1;
			result = res;
		},
		(err) => {
			status = -1;
			result = err;
		}
	);
	// 返回一个对象,只需要提供read方法
	return {
		read() {
			switch (status) {
				case 0:
					throw callPromise;
				case 1:
					return result;
				case -1:
					throw result;
			}
		},
	};
}

这样,子组件通过调用加工函数返回的对象上的read方法,即可根据请求的状态优雅地加载组件了

// 获取加工后的对象
const data = wrapPromise(promise);

// 在子组件中使用
function SubComponent() {
	const data = myData.read();
	return <div>{data}</div>;
}

请求数据的时机

有了 Suspense 和加工函数,我们还要知道该在什么地方调用加工函数

  • 在子组件中调用warpPromise然后请求?

    这是不行的,因为 Suspense 更改渲染的组件时会进行组件的重新挂载操作,相当于子组件中的所有操作都重新运行一遍。 重新运行的加工函数又会重新调用 Promise 并返回全新的对象,里面的read方法也会继续抛出错误,从而使得 Suspense 一直渲染 fallback 中的内容

  • 在文件最外层调用?

    这是可行的,组件内可以正常访问到外面的数据。但是数据写死了不太好控制,只能够做一些初始化请求

  • 在父组件中调用?

    在父组件中调用,然后通过 prop 传递给子组件,这是可行的。并且还可以结合其他 Hook,进行灵活地操作

结论

要优雅地在 Suspense 中请求数据,其实只要实现通过抛出异常通知 Suspense 即可

实际开发中通过 promise.then 直接操控自定义的加载遮罩也比较常见,也不必强行使用 Suspense

但是如果需要对数据进行缓存,那么在使用 react-cache 时顺手用上 Suspense 就更方便了

到此这篇关于React之如何在Suspense中优雅地请求数据的文章就介绍到这了,更多相关在Suspense中请求数据内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: React之如何在Suspense中优雅地请求数据

本文链接: https://www.lsjlt.com/news/211237.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • React之如何在Suspense中优雅地请求数据
    目录什么是 Sunpense懒加载挂起懒加载组件的加载过程对需要请求数据的组件使用 Suspensereact-cache自己写一个加工函数请求数据的时机结论什么是 Sunpense...
    99+
    2023-05-17
    在Suspense中请求数据 React Suspense Suspense请求数据
  • react中如何请求远程数据
    这篇文章给大家分享的是有关react中如何请求远程数据的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 请求远程数据的四种方法:1、直接在React组件...
    99+
    2024-04-02
  • react fetch如何请求数据
    这篇文章主要介绍“react fetch如何请求数据”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“react fetch如何请求数据”文章能帮助大家解决问题。react fetch请求数据的方法:1...
    99+
    2023-07-04
  • react如何请求数据异步
    这篇文章主要讲解了“react如何请求数据异步”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“react如何请求数据异步”吧!react请求数据异步的方法:1、通过“npm i redux-t...
    99+
    2023-07-04
  • Python HTTP请求的艺术:优雅地处理网络数据
    写在前面 Python是当下最为流行的编程语言之一,它在爬虫、自动化测试、数据分析等领域有着广泛的应用。HTTP请求是Web应用开发的基础,掌握HTTP请求的艺术可以帮助你更优雅地处理网络数据。 HTTP请求的基础知识 HTTP请求是一个...
    99+
    2024-02-23
    Python, HTTP, 网络数据, 爬虫
  • React组件如何优雅地处理异步数据详解
    目录前言API介绍SuspenseError Boundaries完整方案处理异步请求的子组件外层组件总结前言 我们在编写React应用的时候,常常需要在组件里面异步获取数据。因为异...
    99+
    2022-11-13
    React处理异步数据 React 异步数据
  • go语言如何优雅地处理http请求和响应?
    Go语言因其高效的并发性和易于编写的特性而备受关注。它的HTTP请求和响应处理也同样简洁而优雅。在本文中,我们将探讨如何使用Go语言来处理HTTP请求和响应。 处理HTTP请求 Go语言中,处理HTTP请求的方式非常简单。在处理请求之前,我...
    99+
    2023-08-25
    http git shell
  • react后端请求数据如何实现
    本篇内容主要讲解“react后端请求数据如何实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“react后端请求数据如何实现”吧!react后端请求数据的实现方法:1、在package.json...
    99+
    2023-07-04
  • 数据库连接池管理的艺术:优雅地处理并发请求
    数据库连接池是管理数据库连接的工具,它可以提高数据库访问效率和性能。在高并发的情况下,为了避免数据库服务器过载,需要使用数据库连接池来管理数据库连接。 数据库连接池管理的艺术在于如何在高并发的情况下优雅地处理并发请求。以下是一些技巧: ...
    99+
    2024-02-13
    数据库连接池 并发请求 连接复用 连接泄漏 连接池管理
  • 如何在golang函数中优雅地处理错误
    go 中优雅地处理错误有两种方法:defer 语句用于在函数返回前执行代码,通常用于释放资源或记录错误。recover 语句用于捕获函数中的 panic,并允许程序以更优雅的方式处理错误...
    99+
    2024-05-01
    golang 错误处理
  • 详解如何在React中优雅的使用addEventListener
    目录使用 addEventListener 代替第三方库的事件方法一:state 变化,卸载/绑定事件方法二:使用闭包的方式卸载事件方法三:使用 ref 保存状态优化 state 手...
    99+
    2023-01-31
    React使用addEventListener React addEventListener
  • 如何在Go中优雅地使用Git和Shell函数?
    在Go语言开发过程中,我们经常需要使用Git和Shell函数。Git是一个非常流行的版本控制工具,而Shell函数则可以让我们在Go中执行操作系统命令。在这篇文章中,我们将探讨如何在Go中优雅地使用Git和Shell函数。 Git Gi...
    99+
    2023-10-11
    git shell 函数
  • 在 Spring Boot 中如何优雅地集成 Shell?
    Shell,又称为命令行解释器,是一种运行在操作系统上的编程语言解释器。它可以让用户通过命令行界面来操作计算机,执行各种任务。在很多情况下,我们需要在应用程序中集成 Shell,以便于用户通过命令行的方式来操作应用程序。本文将介绍在 Sp...
    99+
    2023-06-14
    shell spring django
  • 如何在JavaScript中优雅地处理错误
    在JavaScript中,错误处理是一个非常重要的方面。一个健壮的应用程序应该能够处理各种各样的错误,并以一种优雅和信息丰富的方式向用户报告这些错误。 处理错误最常用的一种方法是使用try/catch语句。try/catch语句允许你指定...
    99+
    2024-02-27
  • 如何在 Golang 中优雅地处理错误?
    非常抱歉,由于您没有提供文章标题,我无法为您生成一篇高质量的文章。请您提供文章标题,我将尽快为您生成一篇优质的文章。...
    99+
    2024-05-14
  • 如何在VSCode中优雅地使用框架?
    在当今软件开发领域,框架是开发者不可或缺的利器之一。它能够帮助开发者快速构建应用程序,提高开发效率,降低开发成本。而作为一款流行且强大的代码编辑器,Visual Studio Code...
    99+
    2024-04-02
  • 如何在ASP面试中,优雅地使用Spring函数?
    在ASP面试中,Spring函数的使用是一个非常重要的话题。Spring函数可以使我们的代码更加简洁、优雅、高效,为我们的开发工作带来极大的便利。在本文中,我们将探讨如何在ASP面试中优雅地使用Spring函数,帮助你在面试中脱颖而出。 一...
    99+
    2023-07-29
    面试 函数 spring
  • 如何在 Laravel 中优雅地使用 Go 存储函数?
    Laravel 是一个流行的 PHP 框架,它提供了很多强大的功能,包括高效的路由、ORM、模板引擎等。但是,在处理大量数据时,Laravel 的性能并不总是最优的。为了提高性能,很多开发者开始将一些计算密集型的操作放到其他语言中进行处理,...
    99+
    2023-11-08
    存储 laravel 函数
  • vue中如何在vuex的actions中请求数据
    这篇文章给大家分享的是有关vue中如何在vuex的actions中请求数据的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。代码actions.js   getC...
    99+
    2024-04-02
  • Python和Git:如何优雅地管理大数据?
    在当今信息化时代,数据已成为企业和个人必不可少的资产。随着数据量的不断增长,如何有效地管理和处理数据已经成为一个亟待解决的问题。Python和Git是两个非常有用的工具,可以帮助我们优雅地管理大数据。 Python是一种高级编程语言,被广...
    99+
    2023-10-13
    git 大数据 numy
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作