作者选择了 Creative Commons以作为 Write for Donations计划的一部分获得捐赠。
介绍
作为JavaScript的网络开发者,同步代码赋予了您运行部分代码的能力,而其他部分仍在等待数据或解析. 这意味着你的应用程序中的重要部分 将不必等待不重要的部分 然后再制作。 通过同步代码,您也可以通过请求并显示新信息来更新您的应用程序,即使长函数和请求正在背景处理中,也给用户一个平滑的经验.
在[反应] (https://reactjs.org/)开发中,同步编程呈现出独特的问题. 例如,当使用React [功能组件] (https://andsky.com/tech/tutorials/how-to-create-custom-components-in-react# step-4-%E2%80%94-building-a-functional-component)时,同步函数可以创建无限回路. 当一个组件加载时,它可以启动一个同步函数,当一个同步函数解决后,它可以触发一个会使组件召回一个同步函数的重置. 此教程将解释如何用一种特殊的[叫作`使用效果' (https://reactjs.org/docs/hooks-effect.html)来避免这种情况,该功能只有在特定数据变化时才能运行. 这会让您故意运行同步代码,而不是在每个渲染周期上运行.
同步代码并不限于对新数据的请求. React有一个内置系统,用于_lazy加载_组件,或者只在用户需要时才加载. 当结合Create React App中默认的 [webpack] (https://webpack.js.org/] 配置时,可以将代码分拆出来,将一个大应用程序缩小为可以按需要加载的更小的块. React有一个叫"Suspense"的特殊组件,在浏览器装入您的新组件时会显示占位符. 在React的未来版本中,您可以使用"Suspense"来将数据装入被嵌入的组件而不会被渲染出阻塞.
在本教程中,您将通过创建一个在河流上显示信息的应用程序来处理React中的非同步数据,并通过setTimeout
模拟对Web APIs的请求。本教程结束时,您将能够使用useEffect
头条加载非同步数据。
前提条件
- 联合国 您需要运行一个开发环境 [Node.js] (https://nodejs.org/en/about/); 此教程在Node.js 版本10.20.1和npm 版本6.14.4. 上进行了测试. 要在 macOS 或 Ubuntu 18.04 上安装此功能,请遵循 [如何在 macOS (https://andsky.com/tech/tutorials/how-to-install-node-js-and-create-a-local-development-environment-on-macos 上安装节点并创建本地开发环境] 或 [如何在 Ubuntu 18.04 (https://andsky.com/tech/tutorials/how-to-install-node-js-on-ubuntu-18-04 上安装节点.js] 的 ** 部分使用 PPA** 。
与Create React App相接而来的一种反应开发环境,非必需锅炉板被取出. 要设置此选项, 请遵循 [* 步骤1 — 创建一个空项目** , 如何管理响应类组件的状态教程] (https://andsky.com/tech/tutorials/how-to-manage-state-on-react-class-components# step-1-%E2%80%94-creating-an-empty-project) 。 此教程将使用
async- tutorial
为项目名称 。 - 联合国 你们将使用
反应事件
和钩子
,包括使用国
和使用减少器
钩子。 您可以在 [How to Handle DOM and Window Events with React] (https://andsky.com/tech/tutorials/how-to-handle-dom-and-window-events-with-react) 教程中了解事件, 以及 Hooks at [Hooks with Hooks on React Inductions] (https://andsky.com/tech/tutorials/how-to-manage-state-on-react-class-components). - 联合国 您还需要JavaScript 和 HTML 的基本知识, 您可以在 our [How To Build a website with HTML series] (https://www.digitalocean.com/community/tutorial_series/how-to-build-a-website-with-html) 和 [How To Code in JavaScript] (https://www.digitalocean.com/community/tutorial_series/how-to-code-in-javascript) 中找到这些知识 。 CSS的基本知识也是有用的,你可以在Mozilla开发者网络中找到. .
步骤 1 — 使用useEffect
加载非同步数据
在此步骤中,您将使用useEffect
链接将非同步数据加载到样本应用程序中。您将使用链接防止不必要的数据采集,在数据加载时添加位置持有人,并在数据解决时更新组件。
要探索主题,您将创建一个应用程序,以显示有关世界上最长的河流的信息. 您将使用非同步函数加载数据,该函数模拟对外部数据源的请求。
首先,创建一个名为RiverInformation
的组件,创建目录:
1mkdir src/components/RiverInformation
在文本编辑器中打开RiverInformation.js
:
1nano src/components/RiverInformation/RiverInformation.js
然后添加一些位置持有人内容:
1[label async-tutorial/src/components/RiverInformation/RiverInformation.js]
2import React from 'react';
3
4export default function RiverInformation() {
5 return(
6 <div>
7 <h2>River Information</h2>
8 </div>
9 )
10}
保存并关闭文件. 现在您需要导入并将新组件转换为您的 root 组件。
1nano src/components/App/App.js
通过在突出代码中添加导入并渲染组件:
1[label async-tutorial/src/components/App/App.js]
2import React from 'react';
3import './App.css';
4import RiverInformation from '../RiverInformation/RiverInformation';
5
6function App() {
7 return (
8 <div className="wrapper">
9 <h1>World's Longest Rivers</h1>
10 <RiverInformation />
11 </div>
12 );
13}
14
15export default App;
保存并关闭文件。
最后,为了使应用程序更容易阅读,添加一些风格。
1nano src/components/App/App.css
通过将CSS替换为以下来添加一些包装到包装
类:
1[label async-tutorial/src/components/App/App.css]
2.wrapper {
3 padding: 20px
4}
保存并关闭文件. 当您这样做时,浏览器将更新并渲染基本组件。
在本教程中,您将创建通用 services 来返回数据. 服务是指任何可重复使用的代码来完成特定任务. 您的组件不需要知道该服务是如何获取信息的。
在src/
目录下创建一个名为服务
的新目录:
1mkdir src/services
此目錄會保留您的非同步函數. 開啟名為 'rivers.js' 的檔案:
1nano src/services/rivers.js
在文件中,导出一个名为getRiverInformation
的函数,返回承诺。在承诺中,添加一个setTimeout
函数,在1500
毫秒后解决承诺。
1[label async-tutorial/src/services/rivers.js]
2export function getRiverInformation() {
3 return new Promise((resolve) => {
4 setTimeout(() => {
5 resolve({
6 continent: 'Africa',
7 length: '6,650 km',
8 outflow: 'Mediterranean'
9 })
10 }, 1500)
11 })
12}
在本片中,您正在硬编码河流信息,但此函数将类似于您可能使用的任何非同步函数,例如API调用。
保存并关闭文件。
现在您有一个返回数据的服务,您需要将其添加到您的组件中,这有时会导致问题,假设您在组件内呼叫了非同步函数,然后使用useState
链接将数据设置为变量。
1import React, { useState } from 'react';
2import { getRiverInformation } from '../../services/rivers';
3
4export default function RiverInformation() {
5 const [riverInformation, setRiverInformation] = useState({});
6
7 getRiverInformation()
8 .then(d => {
9 setRiverInformation(d)
10 })
11
12 return(
13 ...
14 )
15}
当您设置数据时,胡克变更会触发组件重现。当组件重现时,getRiverInformation
函数将再次运行,当它解决时将设置状态,这将触发另一个重现。
为了解决这个问题,React 有一个名为useEffect
的特殊,只有当特定数据发生更改时才会运行。
[ ] [ ] [ ] [ ] [ ] ] [ ] [ ] ] [ ] [ ] ] [ ] [ ] ] [ ] [ ] ] [ ] [ ] ] [ ] [ ] ] [ ] ] [ ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [ ] ] [
打开RiverInformation.js
:
1nano src/components/RiverInformation/RiverInformation.js
使用useState
来创建一个名为riverInformation
的变量和一个名为setRiverInformation
的函数。当非同步函数解决时,您将通过设置riverInformation
来更新该组件。然后将getRiverInformation
函数包裹到useEffect
。请确保将空数列作为第二个参数。当承诺解决时,请用setRiverInformation
函数更新riverInformation
:
1[label async-tutorial/src/components/RiverInformation/RiverInformation.js]
2import React, { useEffect, useState } from 'react';
3import { getRiverInformation } from '../../services/rivers';
4
5export default function RiverInformation() {
6 const [riverInformation, setRiverInformation] = useState({});
7
8 useEffect(() => {
9 getRiverInformation()
10 .then(data =>
11 setRiverInformation(data)
12 );
13 }, [])
14
15 return(
16 <div>
17 <h2>River Information</h2>
18 <ul>
19 <li>Continent: {riverInformation.continent}</li>
20 <li>Length: {riverInformation.length}</li>
21 <li>Outflow: {riverInformation.outflow}</li>
22 </ul>
23 </div>
24 )
25}
解决非同步函数后,更新一个未分类的列表新信息。
保存和关闭文件. 当你这样做时,浏览器将更新并在函数解决后找到数据:
请注意,该组件在加载数据之前会渲染。非同步代码的优点是,它不会阻止初始渲染。在这种情况下,您有一个组件显示列表而没有任何数据,但您也可以渲染旋转器或可扩展的矢量图形(SVG)。
有时您只需要一次加载数据,例如如果您正在获取用户信息或从未改变的资源列表,但很多时候您的非同步函数将需要一些论点。
要模拟这一点,请为您的服务添加一些更多数据。
1nano src/services/rivers.js
然后添加一个包含几个河流的数据的 object。
1[label async-tutorial/src/services/rivers.js]
2const rivers = {
3 nile: {
4 continent: 'Africa',
5 length: '6,650 km',
6 outflow: 'Mediterranean'
7 },
8 amazon: {
9 continent: 'South America',
10 length: '6,575 km',
11 outflow: 'Atlantic Ocean'
12 },
13 yangtze: {
14 continent: 'Asia',
15 length: '6,300 km',
16 outflow: 'East China Sea'
17 },
18 mississippi: {
19 continent: 'North America',
20 length: '6,275 km',
21 outflow: 'Gulf of Mexico'
22 }
23}
24
25export function getRiverInformation(name) {
26 return new Promise((resolve) => {
27 setTimeout(() => {
28 resolve(
29 rivers[name]
30 )
31 }, 1500)
32 })
33}
保存并关闭文件。接下来,打开App.js
,以便添加更多选项:
1nano src/components/App/App.js
在App.js
中,创建一个 stateful变量,并使用useState
口袋来保持所选河流,然后为每个河流添加一个按钮,使用一个onClick
处理器来更新所选河流。
1[label async-tutorial/src/components/App/App.js]
2import React, { useState } from 'react';
3import './App.css';
4import RiverInformation from '../RiverInformation/RiverInformation';
5
6function App() {
7 const [river, setRiver] = useState('nile');
8 return (
9 <div className="wrapper">
10 <h1>World's Longest Rivers</h1>
11 <button onClick={() => setRiver('nile')}>Nile</button>
12 <button onClick={() => setRiver('amazon')}>Amazon</button>
13 <button onClick={() => setRiver('yangtze')}>Yangtze</button>
14 <button onClick={() => setRiver('mississippi')}>Mississippi</button>
15 <RiverInformation name={river} />
16 </div>
17 );
18}
19
20export default App;
保存并关闭文件。接下来,打开RiverInformation.js
:
1nano src/components/RiverInformation/RiverInformation.js
将名称
拖入作为支撑,并将其传输到getRiverInformation
函数中,请确保将名称
添加到useEffect
的数组中,否则它不会重新启动:
1[label async-tutorial/src/components/RiverInformation/RiverInformation.js]
2import React, { useEffect, useState } from 'react';
3import PropTypes from 'prop-types';
4import { getRiverInformation } from '../../services/rivers';
5
6export default function RiverInformation({ name }) {
7 const [riverInformation, setRiverInformation] = useState({});
8
9 useEffect(() => {
10 getRiverInformation(name)
11 .then(data =>
12 setRiverInformation(data)
13 );
14 }, [name])
15
16 return(
17 <div>
18 <h2>River Information</h2>
19 <ul>
20 <li>Continent: {riverInformation.continent}</li>
21 <li>Length: {riverInformation.length}</li>
22 <li>Outflow: {riverInformation.outflow}</li>
23 </ul>
24 </div>
25 )
26}
27
28RiverInformation.propTypes = {
29 name: PropTypes.string.isRequired
30}
在这个代码中,你还添加了PropTypes
的弱打字系统,这将确保支架是一个字符串。
保存文件. 当你这样做时,浏览器会更新,你可以选择不同的河流. 注意点击时和数据渲染时之间的延迟:
如果你在useEffect
数组中错过了名称
提示,你会在 浏览器控制台中收到构建错误。
1[secondary_label Error]
2Compiled with warnings.
3
4./src/components/RiverInformation/RiverInformation.js
5 Line 13:6: React Hook useEffect has a missing dependency: 'name'. Either include it or remove the dependency array react-hooks/exhaustive-deps
6
7Search for the keywords to learn more about each warning.
8To ignore, add // eslint-disable-next-line to the line before.
在这种情况下,很明显效果不会起作用,但有时您可能会将 prop 数据与组件内部的状态数据进行比较,从而可以丢失组件中的项目的跟踪。
最后要做的是将一些 defensive programming添加到您的组件中,这是一个设计原则,强调您的应用程序的高可用性。
因为你的应用现在,效果将更新riverInformation
与它接收的任何类型的数据. 这通常将是一个对象,但在这种情况下,你可以使用可选的链接(https://andsky.com/tech/tutorials/js-v8-optional-chaining-nullish-coalescing)来确保你不会扔错误。
在RiverInformation.js
中,用可选的链接取代对象点链接的实例。
1[label async-tutorial/src/components/RiverInformation/RiverInformation.js]
2import React, { useEffect, useState } from 'react';
3import PropTypes from 'prop-types';
4import { getRiverInformation } from '../../services/rivers';
5
6export default function RiverInformation({ name }) {
7 const [riverInformation, setRiverInformation] = useState();
8
9 useEffect(() => {
10 getRiverInformation(name)
11 .then(data =>
12 setRiverInformation(data)
13 );
14 }, [name])
15
16 return(
17 <div>
18 <h2>River Information</h2>
19 <ul>
20 <li>Continent: {riverInformation?.continent}</li>
21 <li>Length: {riverInformation?.length}</li>
22 <li>Outflow: {riverInformation?.outflow}</li>
23 </ul>
24 </div>
25 )
26}
27
28RiverInformation.propTypes = {
29 name: PropTypes.string.isRequired
30}
当你这样做时,文件仍然会加载,即使代码引用属性为未定义
而不是对象:
防御性编程通常被认为是最佳实践,但在非同步函数(如 API 调用)上尤其重要,当您无法保证响应时。
在此步骤中,您在 React 中调用了非同步函数. 您使用useEffect
链接来获取信息,而无需触发重新渲染,并通过在useEffect
阵列中添加条件来触发新的更新。
在下一步中,您将对您的应用程序进行一些更改,以便仅在安装时更新组件。
步骤2 - 防止未安装的组件出现错误
在此步骤中,您将防止未安装的组件的数据更新. 由于您永远无法确定何时使用非同步编程将数据解决,因此在删除组件后,数据将始终存在风险。
到本步骤结束时,您将知道如何通过在useEffect
口袋中添加警卫来防止内存泄露,以便在组件安装时才更新数据。
目前的组件将始终安装,所以在从 DOM中删除后,代码不会尝试更新组件,但大多数组件不那么可靠。
要测试问题,请更新App.js
,以便可以添加和删除河流细节。
打开App.js
:
1nano src/components/App/App.js
添加一个按钮来切换河流的细节. 使用useReducer
来创建一个函数来切换细节和一个变量来存储切换状态:
1[label async-tutorial/src/components/App/App.js]
2import React, { useReducer, useState } from 'react';
3import './App.css';
4import RiverInformation from '../RiverInformation/RiverInformation';
5
6function App() {
7 const [river, setRiver] = useState('nile');
8 const [show, toggle] = useReducer(state => !state, true);
9 return (
10 <div className="wrapper">
11 <h1>World's Longest Rivers</h1>
12 <div><button onClick={toggle}>Toggle Details</button></div>
13 <button onClick={() => setRiver('nile')}>Nile</button>
14 <button onClick={() => setRiver('amazon')}>Amazon</button>
15 <button onClick={() => setRiver('yangtze')}>Yangtze</button>
16 <button onClick={() => setRiver('mississippi')}>Mississippi</button>
17 {show && <RiverInformation name={river} />}
18 </div>
19 );
20}
21
22export default App;
保存文件. 当你这样做时,浏览会重新加载,你将能够转移细节。
点击一个河流,然后立即点击 Toggle Details 按钮来隐藏细节。
要修复此问题,您需要取消或忽略useEffect
中的非同步函数。如果您正在使用像 RxJS这样的库,则您可以通过返回useEffect
口袋中的函数来取消非同步操作,当该组件卸载时,您可以使用变量来存储安装状态。
打开RiverInformation.js
:
1nano src/components/RiverInformation/RiverInformation.js
在useEffect
函数中,创建一个名为mounted
的变量并将其设置为true
。
1[label async-tutorial/src/components/RiverInformation/RiverInformation.js]
2
3import React, { useEffect, useState } from 'react';
4import PropTypes from 'prop-types';
5import { getRiverInformation } from '../../services/rivers';
6
7export default function RiverInformation({ name }) {
8 const [riverInformation, setRiverInformation] = useState();
9
10 useEffect(() => {
11 let mounted = true;
12 getRiverInformation(name)
13 .then(data => {
14 if(mounted) {
15 setRiverInformation(data)
16 }
17 });
18 }, [name])
19
20 return(
21 <div>
22 <h2>River Information</h2>
23 <ul>
24 <li>Continent: {riverInformation?.continent}</li>
25 <li>Length: {riverInformation?.length}</li>
26 <li>Outflow: {riverInformation?.outflow}</li>
27 </ul>
28 </div>
29 )
30}
31
32RiverInformation.propTypes = {
33 name: PropTypes.string.isRequired
34}
现在你有变量,你需要能够在组件卸载时扭转它. 使用useEffect
链接,你可以返回一个在组件卸载时运行的函数。
1[label async-tutorial/src/components/RiverInformation/RiverInformation.js]
2
3import React, { useEffect, useState } from 'react';
4import PropTypes from 'prop-types';
5import { getRiverInformation } from '../../services/rivers';
6
7export default function RiverInformation({ name }) {
8 const [riverInformation, setRiverInformation] = useState();
9
10 useEffect(() => {
11 let mounted = true;
12 getRiverInformation(name)
13 .then(data => {
14 if(mounted) {
15 setRiverInformation(data)
16 }
17 });
18 return () => {
19 mounted = false;
20 }
21 }, [name])
22
23 return(
24 <div>
25 <h2>River Information</h2>
26 <ul>
27 <li>Continent: {riverInformation?.continent}</li>
28 <li>Length: {riverInformation?.length}</li>
29 <li>Outflow: {riverInformation?.outflow}</li>
30 </ul>
31 </div>
32 )
33}
34
35RiverInformation.propTypes = {
36 name: PropTypes.string.isRequired
37}
保存文件. 当您这样做时,您将能够在没有错误的情况下切换细节。
当您卸载时,组件useEffect
更新变量. 非同步函数仍会解决问题,但不会对未安装的组件进行任何更改。
在此步骤中,您只在安装组件时更新了应用程序更新状态,您更新了useEffect
链接以追踪组件是否安装,并返回了一个函数以更新当组件卸载时的值。
在下一步中,您将无同步地加载组件,将代码分成更小的包,用户将根据需要加载。
步骤 3 — 懒惰地加载一个组件暂停
和懒惰
在此步骤中,您将使用 React Suspense
和 lazy
来分割代码。随着应用程序的增长,最终构建的大小会随之增加。而不是强迫用户下载整个应用程序,您可以将代码分割成更小的块。 React Suspense
和 lazy
与 webpack 和其他构建系统一起工作,将代码分割成更小的块,用户将能够按需求下载。
到此步骤结束时,您将能够非同步地加载组件,将大型应用程序分解为更小的、更集中的块。
到目前为止,您只使用了非同步加载数据,但您也可以使用非同步加载组件。这个过程通常被称为 代码分割,有助于减少代码包的大小,以便您的用户不必下载完整的应用程序,如果他们只使用部分。
大多数时候,你可以静态导入代码,但你可以导入代码 动态通过调用导入
作为一个函数而不是一个陈述。
1import('my-library')
2.then(library => library.action())
React 提供了一组名为 lazy
和 'Suspense' 的工具. React 'Suspense' 最终将扩展到 处理数据加载,但目前您可以使用它来加载组件。
打开App.js
:
1nano src/components/App/App.js
然后从反应
中导入懒惰
和暂停
:
1[label async-tutorial/src/components/App/App.js]
2import React, { lazy, Suspense, useReducer, useState } from 'react';
3import './App.css';
4import RiverInformation from '../RiverInformation/RiverInformation';
5
6function App() {
7 const [river, setRiver] = useState('nile');
8 const [show, toggle] = useReducer(state => !state, true);
9 return (
10 <div className="wrapper">
11 <h1>World's Longest Rivers</h1>
12 <div><button onClick={toggle}>Toggle Details</button></div>
13 <button onClick={() => setRiver('nile')}>Nile</button>
14 <button onClick={() => setRiver('amazon')}>Amazon</button>
15 <button onClick={() => setRiver('yangtze')}>Yangtze</button>
16 <button onClick={() => setRiver('mississippi')}>Mississippi</button>
17 {show && <RiverInformation name={river} />}
18 </div>
19 );
20}
21
22export default App;
懒惰
和暂停
有两个不同的工作。你使用懒惰
函数来动态导入组件并将其设置为变量。
将Import RiverInformation
从../RiverInformation/RiverInformation
代替为lazy
。 将结果分配给名为RiverInformation
的变量,然后将{show && <RiverInformation name={river} />}
与Suspense
组件和Div>
与Loading Component
的信息包裹到fallback
口头:
1[label async-tutorial/src/components/App/App.js]
2import React, { lazy, Suspense, useReducer, useState } from 'react';
3import './App.css';
4const RiverInformation = lazy(() => import('../RiverInformation/RiverInformation'));
5
6function App() {
7 const [river, setRiver] = useState('nile');
8 const [show, toggle] = useReducer(state => !state, true);
9 return (
10 <div className="wrapper">
11 <h1>World's Longest Rivers</h1>
12 <div><button onClick={toggle}>Toggle Details</button></div>
13 <button onClick={() => setRiver('nile')}>Nile</button>
14 <button onClick={() => setRiver('amazon')}>Amazon</button>
15 <button onClick={() => setRiver('yangtze')}>Yangtze</button>
16 <button onClick={() => setRiver('mississippi')}>Mississippi</button>
17 <Suspense fallback={<div>Loading Component</div>}>
18 {show && <RiverInformation name={river} />}
19 </Suspense>
20 </div>
21 );
22}
23
24export default App;
保存文件. 这样做后,重新加载页面,你会发现该组件已动态加载. 如果你想看到加载消息,你可以 throttle在 Chrome 网页浏览器中的响应。
如果您浏览 Chrome 或 Firefox中的网络**
选项卡,您会发现代码被分成不同的片段。
每个片段都默认得到一个数字,但与Webpack相结合的Create React App,您可以通过动态导入添加评论来设置片段名称。
在App.js
中,在导入
函数中添加webpackChunkName
的评论:RiverInformation
*/`:
1[label async-tutorial/src/components/App/App.js]
2import React, { lazy, Suspense, useReducer, useState } from 'react';
3import './App.css';
4const RiverInformation = lazy(() => import(/* webpackChunkName: "RiverInformation" */ '../RiverInformation/RiverInformation'));
5
6function App() {
7 const [river, setRiver] = useState('nile');
8 const [show, toggle] = useReducer(state => !state, true);
9 return (
10 <div className="wrapper">
11 <h1>World's Longest Rivers</h1>
12 <div><button onClick={toggle}>Toggle Details</button></div>
13 <button onClick={() => setRiver('nile')}>Nile</button>
14 <button onClick={() => setRiver('amazon')}>Amazon</button>
15 <button onClick={() => setRiver('yangtze')}>Yangtze</button>
16 <button onClick={() => setRiver('mississippi')}>Mississippi</button>
17 <Suspense fallback={<div>Loading Component</div>}>
18 {show && <RiverInformation name={river} />}
19 </Suspense>
20 </div>
21 );
22}
23
24export default App;
当你这样做时,浏览器将更新,而RiverInformation
块将有一个独特的名称。
在此步骤中,您无同步地加载了组件. 您使用懒惰
和暂停
来动态导入组件,并在组件加载时显示加载消息。
结论
非同步函数创建高效的用户友好的应用程序. 然而,它们的优点伴随着一些微妙的成本,可以演变为程序中的错误. 现在您有工具,可以让您将大型应用程序分割成更小的部件,并加载非同步数据,同时为用户提供可见的应用程序。
如果您想阅读更多 React 教程,请查看我们的 React 主题页面,或返回 如何在 React.js 系列中编码页面。