- ReactJS 菜鸟教程
- ReactJS 教程
- ReactJS - 简介
- ReactJS - 安装
- ReactJS - 特性
- ReactJS - 优点和缺点
- ReactJS - 架构
- ReactJS - 创建 React 应用程序
- ReactJS - JSX
- ReactJS - 组件
- ReactJS - 嵌套组件
- ReactJS - 使用组件
- ReactJS - 组件集合
- ReactJS - 样式
- ReactJS - 属性(props)
- ReactJS - 使用属性创建组件
- ReactJS - props 验证
- ReactJS - 构造函数
- ReactJS - 组件生命周期
- ReactJS - 事件管理
- ReactJS - 创建事件感知组件
- ReactJS - 在Expense Manager APP中引入事件
- ReactJS - 状态管理
- ReactJS - 状态管理 API
- ReactJS - 无状态组件
- ReactJS - 使用 React Hooks 进行状态管理
- ReactJS - 使用 React 钩子的组件生命周期
- ReactJS - 组件的布局
- ReactJS - 分页
- ReactJS - Material 用户界面
- ReactJS - Http 客户端编程
- ReactJS - 表单编程
- ReactJS - 受控组件
- ReactJS - 不受控制的组件
- ReactJS - Formik
- ReactJS - 条件渲染
- ReactJS - 列表
- ReactJS - 键
- ReactJS - 路由
- ReactJS - 冗余
- ReactJS - 动画
- ReactJS - 引导程序
- ReactJS - 地图
- ReactJS - 表格
- ReactJS - 使用 Flux 管理状态
- ReactJS - 测试
- ReactJS - CLI 命令
- ReactJS - 构建和部署
- ReactJS - 示例
- ReactJS - 钩子简介
- ReactJS - 使用 useState
- ReactJS - 使用 useEffect
- ReactJS - 使用 useContext
- ReactJS - 使用 useRef
- ReactJS - 使用 useReducer
- ReactJS - 使用 useCallback
- ReactJS - 使用 useMemo
- ReactJS - 自定义钩子
- ReactJS - 可访问性
- ReactJS - 代码拆分
- ReactJS - 上下文
- ReactJS - 错误边界
- ReactJS - 转发引用
- ReactJS - 片段
- ReactJS - 高阶组件
- ReactJS - 与其他库集成
- ReactJS - 优化性能
- ReactJS - 分析器 API
- ReactJS - 门户
- ReactJS - 没有 ES6 ECMAScript 的 React
- ReactJS - 没有 JSX 的 React
- ReactJS - 协调
- ReactJS - 引用和 DOM
- ReactJS - 渲染属性
- ReactJS - 静态类型检查
- ReactJS - 严格模式
- ReactJS - Web 组件
- ReactJS - 日期选择器
- ReactJS - Helmet
- ReactJS - 内联样式
- ReactJS - 属性类型
- ReactJS - 浏览器路由器
- ReactJS - DOM
- ReactJS - 旋转木马
- ReactJS - 图标
- ReactJS - 表单组件
- ReactJS - 参考 API
ReactJS - Suspense 组件
在 React 18 中,引入了新功能<Suspense>,它允许我们的组件在渲染之前“等待”任何东西。因此,我们在本教程中介绍了 Suspense 的基础知识。
Suspense 是第一个功能,它使我们能够创建具有更灵敏的用户界面、使用更少浏览器资源的应用程序。它还为开发人员和设计人员提供了一个更加用户友好的 API。
Suspense 强烈地改变了 React 根据我们应用程序组件状态的变化选择在网页上渲染内容的方式。如果我们的 React 应用中的数据(状态数据)发生变化,并且这些更改不需要从服务器重新加载整个页面,React 渲染引擎会更新 UI。
当网页必须根据在搜索框中输入等任何内容刷新列表时,React 过去的运行方式与它与并发渲染的工作方式之间存在显着差异。
以前,如果我们在搜索框中输入一些东西,React 可能会一次更新列表中的许多东西。这可能会导致用户将网页视为缓慢且无响应。它还迫使我们的计算机加班加点,以保持页面的流畅运行。
由于并发渲染,React 现在更强大了。它能够更有效地管理这些更改。因此,当我们在搜索框中输入时,React 可以确保列表以某种方式刷新。
语法
<Suspense fallback={<Loading />}>
<MyComponent />
</Suspense>
道具
- children - 这是我们想要在网页上显示的内容 - 如文本、图像或我们想要显示的任何其他内容。或者我们可以说这是我们想要展示的主要内容。
- fallback - 如果我们想要展示的东西(children )还没有准备好,我们可以有一个备用计划。此备份计划称为“fallback.”。它通常是一些简单的东西,例如加载微调器或基本占位符。
如何使用它?
Suspension 是一项新功能,它允许我们的组件在渲染之前“等待”某些内容。它用于数据获取和等待图像、脚本和其他异步操作加载等。
Suspense 不会检测 Effect 或 Event 处理程序中的数据检索。只有启用了 Suspense 的数据源才会激活 <Suspense> 组件。
例子
因此,我们将使用 React 的一些小应用程序看到<Suspense>功能的一些示例和用法。
示例 - 加载占位符
我们可以在我们网站的某个部分周围放置一个特定的框,并告诉浏览器,“如果这个框内的任何内容需要很长时间才能加载,请显示此加载消息。
假设我们想要显示 “Loading...”正在提取照片列表时发出通知。我们可以这样做——
<Suspense fallback={<LoadingMessage />}>
<PhotosComponent />
</Suspense>
因此,通过这种方式,我们可以在浏览器需要很长时间才能加载时显示加载消息,然后在准备就绪时显示真实内容,从而保持我们的网站看起来漂亮和受欢迎。
现在,让我们创建一个简单的应用程序,该应用程序从 API 获取项目列表
首先,我们需要使用 Create React App 来设置我们的 React 项目。在 src 文件夹中,创建两个组件:ItemList.js 和 LoadingMessage.js。在LoadingMessage.js中,我们将定义一个简单的加载消息组件 -
import React from "react";
function LoadingMessage() {
return <div>Loading...</div>;
}
export default LoadingMessage;
在ItemList.js中,我们将创建一个组件,该组件使用 fetch 函数获取并显示项目列表。您还可以使用 Suspense 组件来处理加载 -
import React, { Suspense, useState, useEffect } from "react";
const fetchItems = () =>
new Promise((resolve) => {
setTimeout(() => {
resolve(["Item 1", "Item 2", "Item 3"]);
}, 2000);
});
function ItemList() {
const [items, setItems] = useState(null);
useEffect(() => {
const fetchData = async () => {
const data = await fetchItems();
setItems(data);
};
fetchData();
}, []);
return (
<div>
<h1>Items</h1>
<ul>
{items && items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
export default ItemList;
在我们的 src/App.js 中,我们将使用 Suspense 组件来包装 ItemList 组件并提供回退 -
import React, { Suspense } from "react";
import ItemList from "./ItemList";
import LoadingMessage from "./LoadingMessage";
function App() {
return (
<div className="App">
<h1>My App</h1>
<Suspense fallback={<LoadingMessage />}>
<ItemList />
</Suspense>
</div>
);
}
export default App;
输出
示例 - 渐进式内容显示
当组件挂起时,回退将由最近的父 Suspense 组件显示。我们可以将多个 Suspense 组件嵌套在一起以创建加载模式。随着下一级别内容变得可访问,每个悬念边界的回退将完成。
假设我们正在创建一个包含两个部分的网页:新闻源和天气小部件,每个部分都有自己的加载动画。因此,这就是我们可以使用多个 Suspense 组件来创建加载序列的方法 -
import React, { Suspense } from "react";
function NewsFeedSpinner() {
return <div>Loading News Feed...</div>;
}
function WeatherWidgetSpinner() {
return <div>Loading Weather Widget...</div>;
}
function NewsFeed() {
// Loading news feed data...
return <div>News Feed Content</div>;
}
function WeatherWidget() {
// Loading weather data...
return <div>Weather Widget Content</div>;
}
function App() {
return (
<Suspense fallback={<NewsFeedSpinner />}>
<NewsFeed />
<Suspense fallback={<WeatherWidgetSpinner />}>
<WeatherWidget />
</Suspense>
</Suspense>
);
}
export default App;
输出
示例 - 处理错误和仅限客户端的内容回退
当我们在 React 中使用流式服务器渲染时,如果组件在服务器上生成问题,React 会继续渲染。相反,它会找到最近的 <Suspense> 组件,并在页面上显示其加载微调器。当网站以这种方式加载时,用户将看到一个微调器。
React 尝试在客户端再次渲染相同的组件。如果仍有问题,React 会显示它。但是,如果客户端没有错误,则不会将错误发送给用户,因为内容最终会成功加载。
我们可以使用它来防止某些组件在服务器上呈现。在服务器环境中抛出一个错误,然后将其包裹在<悬念>边界中,以用回退替换HTML -
import React, { Suspense } from "react";
function Loading() {
return <div>Loading Chat...</div>;
}
function Chat() {
if (typeof window === "undefined") {
throw new Error("Chat should only render on the client.");
}
// The Chat component logic goes here...
return <div>Chat Component (Client Only)</div>;
}
export default function App() {
return (
<div>
<h1>Chat App</h1>
<Suspense fallback={<Loading />}>
<Chat />
</Suspense>
</div>
);
}
输出
在应用程序中,我们使用了 typeof window === “undefined” 来检查组件是否在服务器端执行,如果是,我们抛出一个错误来显示 “Chat” 组件应该只在客户端呈现。
警告
- 如果我们应用程序中的某些内容加载时间过长并卡住,React 就会忘记它在做什么。当它完成时,React 只是从头开始。
- 如果我们的应用程序在加载时显示某些内容,但随后卡住了,它将再次显示加载信息,除非我们使用名为“startTransition”或“useDeferredValue”的特定技巧。
- 当我们的应用程序需要隐藏当前在屏幕上的内容时,因为它再次卡住了,React 会清理一些项目以避免减慢速度。当它完成时,React 将再次显示所有内容并进行更多的清理。