如何在 React 中使用 useEffect Hook 调用 Web API

作者选择Creative Commons接受捐赠,作为Write for DOnations计划的一部分。

介绍

React开发中,Web应用程序编程接口(API) 是单页应用程序 (SPA)设计不可或缺的一部分API 是应用程序以编程方式与服务器通信以向用户提供实时数据并保存用户更改的主要方式。在 React 应用程序中,您将使用 API 加载用户首选项、显示用户信息、获取配置或安全信息以及保存应用程序状态更改。

在本教程中,您将使用useEffectuseStateHooks 在示例应用程序中获取和显示信息,使用JSON 服务器作为本地 API 进行测试。您将在组件首次安装时加载信息并使用 API 保存客户输入。您还将在用户进行更改时刷新数据,并了解如何在卸载组件时忽略 API 请求。在本教程结束时,您将能够将您的 React 应用程序连接到各种 API,并且您将能够发送和接收实时数据。

先决条件

步骤 1 — 创建项目和本地 API

在此步骤中,您将使用JSON server创建一个本地REST API,您将使用它作为测试数据源。稍后,您将构建一个应用程序来显示购物清单并将项目添加到列表中。JSON 服务器将是您的本地 API,并会为您提供一个实时 URL 以供创建请求。使用本地 API,您有机会在您或其他团队开发实时 API 时对组件进行原型设计和测试。GETPOST

在这一步结束时,您将能够创建可以连接到 React 应用程序的本地模拟 API。

在许多敏捷团队中,前端和 API 团队并行处理一个问题。为了在远程 API 仍在开发中开发前端应用程序,您可以创建一个本地版本,您可以在等待完整的远程 API 时使用该版本。

有很多方法可以制作模拟本地 API。您可以使用 Node或其他语言创建一个简单的服务器,但最快的方法是使用 JSON 服务器 Node 包。此项目从JSON 文件创建本地 REST API

首先,安装json-server

  • npm install --save-dev json-server

安装完成后,您将收到一条成功消息:

Output
+ json-server@0.16.1 added 108 packages from 40 contributors and audited 1723 packages in 14.505s 73 packages are looking for funding run `npm fund` for details found 0 vulnerabilities

json-server创建基于JavaScript 对象的 API 键是 URL 路径,值作为响应返回。您将 JavaScript 对象存储在本地并将其提交到您的源代码管理。

打开db.json在应用程序根目录中调用的文件这将是存储您从 API 请求的信息的 JSON:

  • nano db.json

添加一个对象与的键list阵列值与一个id和的一个关键item这将列出购物清单的项目。密钥list最终会为您提供一个 URL,其端点为/list

api-tutorial/db.json
{
  "list": [
    { "id": 1, "item": "bread" },
    { "id": 2, "item": "grapes" }
  ]
}

在此代码段中,您已硬编码breadgrapes作为购物清单的起点。

保存并关闭文件。要运行 API 服务器,您将json-server从命令行使用一个参数指向 API 配置文件。将其作为脚本添加到您的package.json.

打开package.json:

  • nano package.json

然后添加一个脚本来运行 API。此外,添加一个delay属性。这将限制响应,在您的 API 请求和 API 响应之间产生延迟。这将使您深入了解应用程序在等待服务器响应时的行为方式。添加delay1500毫秒。最后,3333使用该-p选项在端口上运行 API,这样它就不会与create-react-app运行脚本冲突

api-tutorial/package.json
{
  "name": "do-14-api",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-scripts": "3.4.3"
  },
  "scripts": {
    "api": "json-server db.json -p 3333 --delay 1500",
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "json-server": "^0.16.1"
  }
}

保存并关闭文件。在新的终端或选项卡中,使用以下命令启动 API 服务器:

  • npm run api

在本教程的其余部分保持运行。

运行该命令时,您将收到列出 API 资源的输出:

Output
> json-server db.json -p 3333 \{^_^}/ hi! Loading db.json Done Resources http://localhost:3333/list Home http://localhost:3333 Type s + enter at any time to create a snapshot of the database

打开http://localhost:3333/list,您将找到实时 API:

API 结果,1

当您在浏览器中打开端点时,您正在使用该GET方法。json-server不限于该GET方法。您也可以执行许多其他 REST 方法。例如,您可以POST新建项目。在一个新的终端窗口或标签上,使用curlPOST与类型的新项application/json

  • curl -d '{"item":"rice"}' -H 'Content-Type: application/json' -X POST http://localhost:3333/list

请注意,您必须在发送内容之前对其进行字符串化。运行该curl命令后,您将收到一条成功消息:

Output
{ "item": "rice", "id": 3 }

如果刷新浏览器,将出现新项目:

更新内容,2

POST请求还将更新db.json文件。请注意这些更改,因为在您处理应用程序时,没有任何障碍可以防止意外保存非结构化或无用的内容。在提交到版本控制之前,请务必检查任何更改。

在此步骤中,您创建了一个本地 API。您学习了如何使用默认值创建静态文件,以及如何使用GET等 RESTful 操作获取或更新这些值POST在下一步中,您将创建服务以从 API 获取数据并在您的应用程序中显示。

第 2 步 – 从 API 获取数据 useEffect

在这一步中,您将使用useEffectHook获取杂货清单您将创建一个服务来使用单独目录中的 API,并在您的 React 组件中调用该服务。调用该服务后,您将使用useStateHook保存数据并在您的组件中显示结果。

在此步骤结束时,您将能够使用Fetch 方法useEffectHook调用 Web API 您还可以保存和显示结果。

现在您有一个可用的 API,您需要一个服务来获取数据和组件以显示信息。从创建服务开始。您可以直接在任何 React 组件内获取数据,但如果您将数据检索功能与显示组件分开,您的项目将更易于浏览和更新。这将允许您跨组件重用方法,在测试中模拟,并在端点更改时更新 URL。

在目录services创建一个名为src目录:

  • mkdir src/services

然后打开一个list.js在文本编辑器中调用的文件

  • nano src/services/list.js

您将使用此文件执行/list端点上的任何操作添加一个函数以使用该fetch函数检索数据

api-tutorial/src/services/list
export function getList() {
  return fetch('http://localhost:3333/list')
    .then(data => data.json())
}

此函数的唯一目标是访问数据并使用该data.json()方法将响应转换为 JSON GET是默认操作,因此您不需要任何其他参数。

除了 之外fetch,还有其他流行的库,例如Axios,它们可以为您提供直观的界面,并允许您添加默认标头或对服务执行其他操作。fetch适用于大多数请求。

保存并关闭文件。接下来,打开App.css并添加一些最小的样式:

  • nano src/components/App/App.css

wrapper通过将 CSS 替换为以下内容,添加具有少量填充的类

api-tutorial/src/components/App/App.css
.wrapper {
    padding: 15px;
}

保存并关闭文件。现在您需要添加代码来检索数据并将其显示在您的应用程序中。

打开App.js:

  • nano src/components/App/App.js

在功能组件中,useEffect当组件加载或某些信息发生变化时,您可以使用Hook 获取数据。有关useEffectHook 的更多信息,请查看如何使用 React 处理异步数据加载、延迟加载和代码拆分您还需要使用useStateHook保存结果

导入useEffectuseState,然后创建一个名为的变量list和一个名为的 settersetList来保存您使用useStateHook从服务中获取的数据

api-tutorial/src/components/App/App.js
import React, { useEffect, useState } from 'react';
import './App.css';

function App() {
  const [list, setList] = useState([]);
  return(
    <>
    </>
  )
}

export default App;

接下来,导入服务,然后在useEffectHook 中调用该服务如果安装了组件,则更新listwith setList要理解为什么你应该检查组件安装设置数据之前,请参阅第2步-在未安装的组件防止错误如何处理异步数据加载,延迟加载,并与之反应代码分裂

目前您只在页面加载时运行一次效果,因此依赖项数组将为空。在下一步中,您将根据不同的页面操作触发效果,以确保您始终拥有最新的信息。

添加以下突出显示的代码:

api-tutorial/src/components/App/App.js

import React, { useEffect, useState } from 'react';
import './App.css';
import { getList } from '../../services/list';

function App() {
  const [list, setList] = useState([]);

  useEffect(() => {
   let mounted = true;
   getList()
     .then(items => {
       if(mounted) {
         setList(items)
       }
     })
   return () => mounted = false;
 }, [])

  return(
    <>
    </>
  )
}

export default App;

最后,循环遍历项目.map并将它们显示在列表中:

api-tutorial/src/components/App/App
import React, { useEffect, useState } from 'react';
import './App.css';
import { getList } from '../../services/list';

function App() {
  const [list, setList] = useState([]);

  useEffect(() => {
    let mounted = true;
    getList()
      .then(items => {
        if(mounted) {
          setList(items)
        }
      })
    return () => mounted = false;
  }, [])

  return(
    <div className="wrapper">
     <h1>My Grocery List</h1>
     <ul>
       {list.map(item => <li key={item.item}>{item.item}</li>)}
     </ul>
   </div>
  )
}

export default App;

保存并关闭文件。当你这样做时,浏览器将刷新,你会找到一个项目列表:

列表项,3

在此步骤中,您将设置一个服务以从 API 检索数据。您学习了如何使用useEffectHook调用服务以及如何设置页面上的数据。您还在JSX 中显示了数据

在下一步中,您将使用向 API 提交数据POST并使用响应来提醒您的用户操作已成功。

第 3 步 – 将数据发送到 API

在此步骤中,您将使用 Fetch API 和POST方法将数据发送回 API 您将创建一个组件,该组件将使用Web 表单通过onSubmit事件处理程序发送数据,并在操作完成时显示成功消息。

在此步骤结束时,您将能够向 API 发送信息,并且能够在请求解决时提醒用户。

向服务发送数据

您有一个显示杂货清单的应用程序,但它不是一个非常有用的杂货应用程序,除非您也可以保存内容。您需要创建一个服务,该服务将为POSTAPI提供一个新项目。

打开src/services/list.js

  • nano src/services/list.js

在该文件中,添加一个函数,该函数将item一个参数作为参数,并使用该POST方法将数据发送到 API。和以前一样,您可以使用 Fetch API。这一次,您将需要更多信息。添加一个选项对象作为第二个参数。包括方法-POST页眉设置-alongContent-Typeapplication/json最后,将新对象发送到body. 请务必使用 将对象转换为字符串JSON.stringify

当您收到响应时,将值转换为 JSON:

教程/src/services/list.js
export function getList() {
  return fetch('http://localhost:3333/list')
    .then(data => data.json())
}

export function setItem(item) {
 return fetch('http://localhost:3333/list', {
   method: 'POST',
   headers: {
     'Content-Type': 'application/json'
   },
   body: JSON.stringify({ item })
 })
   .then(data => data.json())
}

保存并关闭文件。

注意:在生产应用程序中,您需要添加错误处理和检查。例如,如果您拼错了端点,您仍然会收到404响应并且该data.json()方法将返回一个空对象。要解决此问题,您可以检查data.ok属性,而不是将响应转换为 JSON 如果它是假的,你可以抛出一个错误,然后.catch在你的组件中使用该方法向用户显示一条失败消息。

现在您已经创建了一个服务,您需要在您的组件中使用该服务。

打开App.js:

  • nano src/components/App/App.js

formaninput和 submit周围添加一个元素button

api-tutorial/src/components/App/App.js

import React, { useEffect, useState } from 'react';
import './App.css';
import { getList } from '../../services/list';

function App() {
  const [list, setList] = useState([]);

  useEffect(() => {
    let mounted = true;
    getList()
      .then(items => {
        if(mounted) {
          setList(items)
        }
      })
    return () => mounted = false;
  }, [])

  return(
    <div className="wrapper">
      <h1>My Grocery List</h1>
      <ul>
        {list.map(item => <li key={item.item}>{item.item}</li>)}
      </ul>
      <form>
       <label>
         <p>New Item</p>
         <input type="text" />
       </label>
       <button type="submit">Submit</button>
     </form>
    </div>
  )
}

export default App;

确保input用 a包围label以便屏幕阅读器可以访问该表单。将 a 添加type="submit"也是一个很好的做法,button以便很明显角色是提交表单。

保存文件。当您这样做时,浏览器将刷新并且您会找到您的表单。

杂货清单表格

接下来,将 转换input受控组件您需要一个受控组件,以便在用户成功提交新列表项后清除该字段。

首先,使用useStateHook创建一个新的状态处理程序来保存和设置输入信息

api-tutorial/src/components/App/App.js
import React, { useEffect, useState } from 'react';
import './App.css';
import { getList } from '../../services/list';

function App() {
  const [itemInput, setItemInput] = useState('');
  const [list, setList] = useState([]);

  useEffect(() => {
    let mounted = true;
    getList()
      .then(items => {
        if(mounted) {
          setList(items)
        }
      })
    return () => mounted = false;
  }, [])

  return(
    <div className="wrapper">
      <h1>My Grocery List</h1>
      <ul>
        {list.map(item => <li key={item.item}>{item.item}</li>)}
      </ul>
      <form>
        <label>
          <p>New Item</p>
          <input type="text" onChange={event => setItemInput(event.target.value)} value={itemInput} />
        </label>
        <button type="submit">Submit</button>
      </form>
    </div>
  )
}

export default App;

创建状态处理程序后,设置inputtoitemInput的值并通过使用事件处理程序将 传递event.target.valuesetItemInput函数来更新值onChange

现在您的用户可以使用新的列表项填写表单。接下来,您要将表单连接到您的服务。

创建一个名为 的函数handleSubmithandleSubmit将一个事件作为参数并调用event.preventDefault()以阻止表单刷新浏览器。

setItem从服务导入,然后setItem使用函数itemInput内部的值调用handleSubmithandleSubmit通过将其传递给onSubmit事件处理程序连接到表单

api-tutorial/src/components/App/App.js
import React, { useEffect, useState } from 'react';
import './App.css';
import { getList, setItem } from '../../services/list';

function App() {
  const [itemInput, setItemInput] = useState('');
  const [list, setList] = useState([]);

  useEffect(() => {
    let mounted = true;
    getList()
      .then(items => {
        if(mounted) {
          setList(items)
        }
      })
    return () => mounted = false;
  }, [])

  const handleSubmit = (e) => {
    e.preventDefault();
    setItem(itemInput)
  };

  return(
    <div className="wrapper">
      <h1>My Grocery List</h1>
      <ul>
        {list.map(item => <li key={item.item}>{item.item}</li>)}
      </ul>
      <form onSubmit={handleSubmit}>
        <label>
          <p>New Item</p>
          <input type="text" onChange={event => setItemInput(event.target.value)} value={itemInput} />
        </label>
        <button type="submit">Submit</button>
      </form>
    </div>
  )
}

export default App;

保存文件。当您这样做时,您将能够提交值。请注意,您将在网络选项卡中收到成功的响应。但是列表没有更新,输入也没有清除。

提交成功,5

显示成功信息

给用户一些指示他们的操作是成功的总是一个很好的做法。否则,用户可能会多次尝试重新提交一个值,或者可能认为他们的操作失败并会离开应用程序。

为此,请创建一个有状态变量和 setter 函数useState以指示是否向用户显示警报消息。如果alert为 true,则显示<h2>带有消息Submit Successful标记

setItem 承诺解决时,清除输入并设置警报消息:

api-tutorial/src/components/App/App.js
import React, { useEffect, useState } from 'react';
import './App.css';
import { getList, setItem } from '../../services/list';

function App() {
  const [alert, setAlert] = useState(false);
  const [itemInput, setItemInput] = useState('');
  const [list, setList] = useState([]);

  useEffect(() => {
    let mounted = true;
    getList()
      .then(items => {
        if(mounted) {
          setList(items)
        }
      })
    return () => mounted = false;
  }, [])

  const handleSubmit = (e) => {
    e.preventDefault();
    setItem(itemInput)
      .then(() => {
        setItemInput('');
        setAlert(true);
      })
  };

  return(
    <div className="wrapper">
      <h1>My Grocery List</h1>
      <ul>
        {list.map(item => <li key={item.item}>{item.item}</li>)}
      </ul>
      {alert && <h2> Submit Successful</h2>}
      <form onSubmit={handleSubmit}>
        <label>
          <p>New Item</p>
          <input type="text" onChange={event => setItemInput(event.target.value)} value={itemInput} />
        </label>
        <button type="submit">Submit</button>
      </form>
    </div>
  )
}

export default App;

保存文件。当您这样做时,页面将刷新,您将在 API 请求解析后看到一条成功消息。

提交并留言,6

您可以添加许多其他优化。例如,您可能希望在有活动请求时禁用表单输入。您可以在How To Build Forms in React 中了解有关禁用表单元素的更多信息

现在您已提醒用户结果成功,但提醒消息并未消失且列表未更新。要解决此问题,请先隐藏警报。在这种情况下,您希望在短暂的时间(例如一秒钟)后隐藏信息。您可以使用该setTimeout函数来调用setAlert(false),但您需要将其包装起来useEffect以确保它不会在每个组件渲染上运行。

在里面App.js创建一个新的效果并将 传递alert给触发器数组。这将导致效果在任何时间alert更改时运行请注意,这将运行如果alert从变化falsetrue,但它也将在运行时alert从变化truefalse因为你只有在显示它要隐藏的警报,添加一个条件的影响里面只运行setTimeout,如果alerttrue

api-tutorial/src/components/App/App.js
import React, { useEffect, useState } from 'react';
import './App.css';
import { getList, setItem } from '../../services/list';

function App() {
  const [alert, setAlert] = useState(false);
  const [itemInput, setItemInput] = useState('');
  const [list, setList] = useState([]);
    ...

  useEffect(() => {
    if(alert) {
      setTimeout(() => {
        setAlert(false);
      }, 1000)
    }
  }, [alert])

  const handleSubmit = (e) => {
    e.preventDefault();
    setItem(itemInput)
      .then(() => {
        setItemInput('');
        setAlert(true);
      })
  };

  return(
    <div className="wrapper">
      ...
    </div>
  )
}

export default App;

setTimeout1000几毫秒运行该函数以确保用户有时间读取更改。

保存文件。现在你有一个效果会在alert发生变化时运行如果有活动警报,它将启动超时功能,一秒后关闭警报。

隐藏警报,7

刷新获取的数据

现在您需要一种方法来刷新陈旧的数据列表。为此,您可以向useEffectHook添加一个新触发器以重新运行getList请求。为确保您拥有最相关的数据,您需要一个触发器,该触发器将在远程数据发生更改时随时更新。幸运的是,您可以重用alert状态来触发另一次数据刷新,因为您知道它会在用户更新数据时运行。和以前一样,您必须计划这样一个事实,即每次alert更改时都会运行效果,包括警报消息消失的时间。

这一次,该效果还需要在页面加载时获取数据。创建一个条件,如果list.length为真,则将在数据获取之前退出函数– 表示您已经获取了数据 – 并且alert是 –false表示您已经刷新了数据。确保将alert添加list到触发器数组中:

import React, { useEffect, useState } from 'react';
import './App.css';
import { getList, setItem } from '../../services/list';

function App() {
  const [alert, setAlert] = useState(false);
  const [itemInput, setItemInput] = useState('');
  const [list, setList] = useState([]);

  useEffect(() => {
    let mounted = true;
    if(list.length && !alert) {
      return;
    }
    getList()
      .then(items => {
        if(mounted) {
          setList(items)
        }
      })
    return () => mounted = false;
  }, [alert, list])

  ...

  return(
    <div className="wrapper">
      ...
    </div>
  )
}

export default App;

保存文件。当您这样做时,数据将在您提交新项目后刷新:

列表刷新,8

在这种情况下,alertlist状态没有直接关系但是,它确实与会使旧数据无效的事件同时发生,因此您可以使用它来刷新数据。

防止更新未安装的组件

您需要考虑的最后一个问题是确保您没有在未安装的组件上设置状态。您有一个解决方案来let mounted = true获取数据的效果,但该解决方案不适用于handleSubmit,因为它不是效果。卸载时无法返回将值设置为 false 的函数。此外,向每个函数添加相同的检查将是低效的。

为了解决这个问题,您可以通过mounteduseEffectHook取出并将其保持在组件级别上来创建一个供多个函数使用的共享变量您仍将使用该函数将值设置falseuseEffect.

在里面App.jsmounted在函数的开始处声明然后在其他异步函数中设置数据之前检查组件是否已安装。确保删除函数mounted内的声明useEffect

api-tutorial/src/components/App/App.js
import React, { useEffect, useState } from 'react';
import './App.css';
import { getList, setItem } from '../../services/list';

function App() {
  const [alert, setAlert] = useState(false);
  const [itemInput, setItemInput] = useState('');
  const [list, setList] = useState([]);
  let mounted = true;

  useEffect(() => {
    if(list.length && !alert) {
      return;
    }
    getList()
      .then(items => {
        if(mounted) {
          setList(items)
        }
      })
    return () => mounted = false;
  }, [alert, list])

  useEffect(() => {
    if(alert) {
      setTimeout(() => {
        if(mounted) {
          setAlert(false);
        }
      }, 1000)
    }
  }, [alert])

  const handleSubmit = (e) => {
    e.preventDefault();
    setItem(itemInput)
      .then(() => {
        if(mounted) {
          setItemInput('');
          setAlert(true);
        }
      })
  };

  return(
    <div className="wrapper">
      ...
    </div>
  )
}

export default App;

当您进行更改时,您将在运行 React 应用程序的终端中收到错误消息:

Error
Assignments to the 'mounted' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside useEffect react-hooks/exhaustive-deps

React 提醒您变量不稳定。每当有重新渲染时,它都会重新计算变量。通常,这将确保获得最新信息。在这种情况下,您依靠该变量来持久化。

解决方案是另一个名为useRef. useRef钩将保留的变量为组件的寿命。唯一的技巧是获取使用该.current属性所需的值

在 内部App.jsmounted使用useRefHook转换为引用然后将每个用法转换mountedmounted.current

api-tutorial/src/components/App/App.js
import React, { useEffect, useRef, useState } from 'react';
import './App.css';
import { getList, setItem } from '../../services/list';

function App() {
  const [alert, setAlert] = useState(false);
  const [itemInput, setItemInput] = useState('');
  const [list, setList] = useState([]);
  const mounted = useRef(true);

  useEffect(() => {
    mounted.current = true;
    if(list.length && !alert) {
      return;
    }
    getList()
      .then(items => {
        if(mounted.current) {
          setList(items)
        }
      })
    return () => mounted.current = false;
  }, [alert, list])

  useEffect(() => {
    if(alert) {
      setTimeout(() => {
        if(mounted.current) {
          setAlert(false);
        }
      }, 1000)
    }
  }, [alert])

  const handleSubmit = (e) => {
    e.preventDefault();
    setItem(itemInput)
      .then(() => {
        if(mounted.current) {
          setItemInput('');
          setAlert(true);
        }
      })
  };

  return(
    <div className="wrapper">
       ...
    </div>
  )
}

export default App;

此外,在清理函数中为useEffect. 清除功能将始终在效果重新运行之前运行。这意味着() => mounted.current = false每次alertlist更改时都会运行清理函数为避免任何错误结果,请务必在效果开始时更新mounted.currentto true然后您可以确定它只会在false卸载组件时设置为

保存并关闭文件。当浏览器刷新时,您将能够保存新的列表项:

再次保存,9

Note: It is a common problem to accidentally rerun an API multiple times. Every time a component is removed and then remounted, you will rerun all the original data fetching. To avoid this, consider a caching method for APIs that are particularly data heavy or slow. You can use anything from memoizing the service calls, to caching with service workers, to a custom Hook. There are a few popular custom Hooks for caching service calls, including useSWR and react query.

No matter which approach you use, be sure to consider how you will invalidate the cache because there are times where you’ll want to fetch the newest data.

In this step, you sent data to an API. You learned how to update the user when the data is submitted and how to trigger a refresh on your list data. You also avoided setting data on unmounted components by using the useRef Hook to store the status of the component so that it can be used by multiple services.

Conclusion

APIs give you the ability to connect to many useful services. They allow you to store and retrieve data even after a user closes their browser or stops using an application. With well organized code, you can isolate your services from your components so that your components can focus on rendering data without knowing where the data is originating. Web APIs extend your application far beyond the capabilities of a browser session or storage. They open your application to the whole world of web technologies.

如果您想阅读更多 React 教程,请查看我们的React 主题页面,或返回“如何在 React.js 中编码”系列页面

觉得文章有用?

点个广告表达一下你的爱意吧 !😁