
React 是请求一个专注的组件库。因此,远程它对如何请求远程数据没有什么建议。数据如果要通过 HTTP 请求数据并将其发送到 Web API,请求可以考虑下面四种方法。远程
内联写法 集中管理 自定义 Hook react-query/swr注意:在本文中,数据我将使用 fetch 进行 HTTP 调用,请求但是远程这些模式也适用于 Axios 之类的替代方法。另外,数据如果你使用的请求是 GraphQ L,还可以考虑使用 Apollo 之类的远程其他不错的选择。这篇文章假设你正在调用传统的数据 REST API。
方式1:内联
这是请求最简单,最直接的远程选择。在 React 组件中进行 HTTP 调用并处理响应。数据
fetch("/users").then(response => response.json());看起来很简单。但是这个示例忽略了加载状态,错误处理,声明和设置相关状态等。在现实世界中, HTTP 调用看起来更像这样。
import React, { useState, useEffect } from "react"; export default function InlineDemo() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetch(`${process.env.REACT_APP_API_BASE_URL}users`) .then(response => { if (response.ok) return response.json(); throw response; }) .then(json => { setUsers(json); }) .catch(err => { console.error(err); setError(err); }) .finally(() => { setLoading(false); }); }, []); if (loading) return "Loading..."; if (error) return "Oops!"; return users[0].username; }对于一个简单的网站模板应用程序,只要发起几个请求,就可以正常工作。但是上面的状态声明和 useEffect 都是模版。如果我要进行许多 HTTP 调用,我不想为每个调用重复和维护大约 20 行代码。内联调用让你的代码变得很丑。
看一下我们要解决的一些问题:
声明加载状态 声明错误状态 将错误打印到控制台 检查响应是否通过返回 200 response.ok 如果响应正常,将响应转换为 json 并返回 promise 如果响应不正确,抛出错误 在 finally 中隐藏加载状态,以确保 Loading 即使发生错误也被隐藏 声明一个空的依赖项数组,以便 useEffect 只运行一次这只是一个简单的示例,它忽略了许多其他相关问题。
方式2:文件夹集中管理
如果我们在一个文件夹中处理所有 HTTP 调用会怎么样? 使用这种方法,我们创建了一个名为 services 的文件夹,并且把进行 HTTP 调用的函数都放进去。service 是比较流行的术语,我在下面也讨论了很多好的替代名称,如 client 或 api。服务器托管

要点是,所有的 HTTP 调用都是通过纯 JavaScript 函数处理的,存储在一个文件夹中。这是一个集中的 getUsers 函数:
export function getUsers() { return fetch(`${process.env.REACT_APP_API_BASE_URL}users`).then(response => response.json() ); }下面是对 getUsers 函数的调用:
import React, { useState, useEffect } from "react"; import { getUsers } from "./services/userService"; export default function CentralDemo() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { getUsers() .then(json => { setUsers(json); setLoading(false); }) .catch(err => { console.error(err); setError(err); }); }, []); if (loading) return "Loading..."; if (error) return "Oops!"; return users[0].username; }然而这并没有太简化请求调用。主要的好处是它可以强制一致地处理 HTTP 调用。其思想是这样的:当相关函数一起处理时,更容易一致地处理它们。如果 userService 文件夹中充满了进行 HTTP 调用的函数,那么我可以很容易地确保它们始终如一地这样做。此外,如果调用被复用,则很容易从这个集中位置调用它们。
然而,我们还可以做得更好。
方式3:自定义Hook
借助 React Hooks 的魔力,我们终于可以集中处理重复的逻辑。那么如何创建一个自定义 useFetch 钩子来简化我们的 HTTP 调用呢?
import { useState, useEffect, useRef } from "react"; // This custom hook centralizes and streamlines handling of HTTP calls export default function useFetch(url, init) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const prevInit = useRef(); const prevUrl = useRef(); useEffect(() => { // Only refetch if url or init params change. if (prevUrl.current === url && prevInit.current === init) return; prevUrl.current = url; prevInit.current = init; fetch(process.env.REACT_APP_API_BASE_URL + url, init) .then(response => { if (response.ok) return response.json(); setError(response); }) .then(data => setData(data)) .catch(err => { console.error(err); setError(err); }) .finally(() => setLoading(false)); }, [init, url]); return { data, loading, error }; }你的服务器租用可能看起来不一样,但我发现这个基本的使用方法很有用。这个 Hook 极大地简化了所有调用。看看使用这个 Hook 需要多少代码 :
import React from "react"; import useFetch from "./useFetch"; export default function HookDemo() { const { data, loading, error } = useFetch("users"); if (loading) return "Loading..."; if (error) return "Oops!"; return data[0].username; }对于许多应用程序,你只需要一个这样的自定义Hook。但是这个Hook已经很复杂了,并且它消除了许多问题。
但是还有很多我们没有考虑到的点:缓存?、如果客户端的连接不可靠,如何重新获取?你想在用户重新调整标签时重新获取新数据吗?如何消除重复查询?
你可以不断完善这个自定义Hook来完成所有这些操作。但是,您应该只需要方式4:
方式4:react-query/swr
使用 react-query或swr,可以为我们处理缓存、重试、重复查询等等。我不必维护自己的自定义Hook了。而且每个 HTTP 调用都需要很少的代码:
import React from "react"; import { getUsers } from "./services/userService"; import { useQuery } from "react-query"; export default function ReactQueryDemo() { const { data, isLoading, error } = useQuery("users", getUsers); if (isLoading) return "Loading..."; if (error) return "Oops!"; return data[0].username; }对于大多数应用程序来说,今天这是我的首选。这是完整的代码:https://codesandbox.io/s/4-ways-to-handle-restful-http-in-react-k3xug,你可以自己进行比较。
华硕F81se系列电脑的用户在安装Ubuntu12.04系统是出现了错误,导致Ubuntu12.04安装失败,那么是什么原因导致系统安装失败呢?想要在华硕F81se上使用Ubuntu12.04系统怎么办?下面小编就给大家介绍下解决方法。问题:从ubuntu官网上下载了12.04的安装包,下了个usb installer,把系统烧到u盘以后,在u盘里run了下,总是出现下面的错误:Cannot allocate resource for EISA slot 1Cannot allocate resource for EISA slot 2Cannot allocate resource for EISA slot 3Cannot allocate resource for EISA slot 4Cannot allocate resource for EISA slot 5Cannot allocate resource for EISA slot 6Cannot allocate resource for EISA slot 7Cannot allocate resource for EISA slot 8解决方法:华硕电脑开机的时候,按F2进入bios设置,选择security选项,会看到如下图所示:按键盘上的上下键,把光标移动到I/O Interface Security 选项,敲回车,进入下图:默认情况下,这里面的所有的选项都是UNLOCKED 将最后一个选项New Card Interface 设置为LOCKED 这样就可以进入系统了,有人提到要将Wireless NetWork Interface 也设置为LOCED 这样有利于安装,要注意:ODD Interface 和USB Interface 千万不要设置为LOCKED 这样就关闭了USB 和光驱的功能。装完系统以后要把New Card Interface 设置为LOCKED,否则ubuntu 12.04将启动不了,其他的都要设置为UBLOCKED,到这里,基本上系统装的就没问题了。上面就是Ubuntu 12.04在华硕F81se电脑上安装失败的解决方法介绍了,只要你安装本文的步骤实施,你就能轻松使用上Ubuntu 12.04系统了。
windows 7系统中不能把程序锁定到任务栏的解决方法图文讲解
Windows7自带Update更新系统失败该如何解决
windows 7系统怎么创建拨号连接?