学习如何轻松构建可伸缩的 React 应用程序:数据获取
# React 中服务端数据获取的方式
在大多数 React 应用程序中,应用程序需要来自 API 或服务器的数据才能正常运行。也会将数据从应用程序提交到服务器以接收某种响应。有几种方法可以将此数据发送/获取到 API 或服务器,可以使用内置的 API 或外部 npm 包来实现。
# fetch
这是 JavaScript 和 React 应用程序中常用的 API。Fetch 提供了 Request 和 Response 对象(以及其他与网络请求相关的内容)。这将使它们在将来需要的任何地方都可以使用,无论是用于 Service Worker、缓存 API 还是其他处理或修改请求和响应的类似功能,或者任何可能需要您编写程序来生成响应的地方。
fetch()
方法接受一个必需参数,即要获取的资源的路径,返回一个 Promise
,解析该请求的响应。
import React from "react";
function App() {
const [data, setData] = React.useState(null);
React.useEffect(() => {
fetch("https://api.example.com/items")
.then((response) => response.json())
.then((data) => setData(data));
}, []);
return (
<div>
<h1>Items</h1>
<ul>{data && data.map((item) => <li key={item.id}>{item.name}</li>)}</ul>
</div>
);
}
export default App;
# axios
Axios 是一个基于 Promise
的 node.js 和浏览器 HTTP 客户端。它是同构的(即可以在浏览器和 nodejs 中使用相同的代码库)。在服务器端,它使用本地的 node.js http
模块,而在客户端(浏览器)中,它使用 XMLHttpRequests
。
安装:
代码语言:javascript复制npm install axios
使用:
代码语言:javascript复制import React from "react";
function App() {
const [data, setData] = React.useState(null);
React.useEffect(() => {
axios.get("https://api.example.com/items").then((response) => {
setData(response.data);
});
}, []);
return (
<div>
<h1>Items</h1>
<ul>{data && data.map((item) => <li key={item.id}>{item.name}</li>)}</ul>
</div>
);
}
export default App;
# GraphQL
GraphQL 是用于 API 的查询语言,也是用现有数据来满足这些查询的运行时。GraphQL 提供了 API 中数据的完整且易于理解的描述,使客户端能够精确地请求所需的数据,避免了不必要的数据传输,使得 API 能够随着时间的推移更容易地发展,并提供了强大的开发者工具。
向您的 API 发送 GraphQL 查询,只获取您所需的数据,没有多余的内容。GraphQL 查询总是返回可预测的结果,使用 GraphQL 的应用程序速度快且稳定,因为它们控制获取的数据,而不是由服务器来控制。
安装:
代码语言:javascript复制npm install graphql @apollo/client
使用:
代码语言:javascript复制import React from "react";
import { ApolloClient, InMemoryCache, ApolloProvider, gql, useQuery } from "@apollo/client";
const client = new ApolloClient({
uri: "https://countries.trevorblades.com/",
cache: new InMemoryCache(),
});
const GET_COUNTRIES_AND_CAPITALS = gql`
query GetCountriesAndCapitals {
countries {
code
name
capital
}
}
`;
function CountriesList() {
const { loading, error, data } = useQuery(GET_COUNTRIES_AND_CAPITALS);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (
<ul>
{data.countries.map((country) => (
<li key={country.code}>
{country.name} - {country.capital}
</li>
))}
</ul>
);
}
function CountriesAndCapitals() {
return (
<ApolloProvider client={client}>
<div>
<h1>Countries and Capitals</h1>
<CountriesList />
</div>
</ApolloProvider>
);
}
export default CountriesAndCapitals;
# 缓存数据
在大多数 React 应用程序中,通常需要计算数据或从 API 获取数据。然而,当组件重新渲染时,这些数据并不总是需要重新计算或重新获取。有几种方法可以在 React 中实现数据缓存。
# Memoization
Memoization 是一种优化技术,主要用于通过存储昂贵的函数调用结果,并在再次出现相同输入时返回缓存的结果来优化计算机程序。
简单来说,Memoization 是指将结果存储在内存中。Memoization 函数通常更快,因为如果使用相同的参数再次调用函数,则不会重新执行函数,而是从缓存中获取结果。
在 React 中,我们可以通过以下两种方式实现 Memoization:
useMemo
- React 提供了一个内置的钩子函数
useMemo
允许您对耗费性能的函数进行记忆化,以避免在每次重新渲染时调用它们 - 只需传入一个函数和一个依赖数组,
useMemo
将仅在依赖中的一个值发生变化时重新计算记忆化的值
import React, { useMemo } from "react";
function App() {
const [count, setCount] = React.useState(0);
const expensiveValue = useMemo(() => {
// 这个函数只有在 `count` 改变时才会重新计算
return count * 2;
}, [count]);
return (
<div>
<h1>Expensive Value: {expensiveValue}</h1>
<button onClick={() => setCount(count 1)}>Increment</button>
</div>
);
}
export default App;
useCallback
- React 提供了一个内置的钩子函数
useCallback
,允许您对耗费性能的函数进行记忆化,以避免在每次重新渲染时调用它们 - 只需传入一个函数和一个依赖数组,
useCallback
将仅在依赖中的一个值发生变化时重新计算记忆化的函数
import React, { useCallback } from "react";
function App() {
const [count, setCount] = React.useState(0);
const handleClick = useCallback(() => {
// 这个函数只有在 `count` 改变时才会重新计算
console.log(count);
}, [count]);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={handleClick}>Increment</button>
</div>
);
}
export default App;
# 状态管理
状态管理是另一种在 React 应用程序中缓存数据并使用它的方法。从 API 缓存的数据可以存储在我们的状态管理中,然后在我们的应用程序中全局使用。尽管数据被缓存,但在刷新页面时,它将丢失数据,需要重新获取。此外,您可以获取数据并将其存储在 React 应用程序状态中。
# React Query
React Query 是一个库,用于处理 React 应用程序中的数据获取和管理。它提供了许多有用的功能,如数据缓存、自动重试、请求取消和突变。
React Query 的目标是提供一个简单的 API,让数据获取和管理变得更加容易,并且可以与现有的代码库集成。通过使用 React Query,开发者可以快速地处理数据获取和管理,同时保持 React 应用程序的高性能和可伸缩性。
# 安装
代码语言:javascript复制npm install react-query
# 使用
代码语言:javascript复制import React from "react";
import { useQuery, QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();
function Demo() {
const { isLoading, error, data } = useQuery("repoData", () =>
fetch("https://api.github.com/repos/tannerlinsley/react-query").then((res) => res.json())
);
if (isLoading) return "Loading...";
if (error) return "An error has occurred: " error.message;
return (
<div>
<h1>{data.name}</h1>
<p>{data.description}</p>
<strong>