请求远程数据的四种方法: 1、直接在React组件中进行HTTP调用,并处理响应; 2、创建一个文件夹,把所有进行HTTP调用的函数放进去,集中请求数据并处理响应; 3、自定义Hook来请求数据; 4.使用“react-query”或swr请求数据。

从“react”导入React,{useState,useEffect}; 导出默认函数 InlineDemo() { const [用户,setUsers] = useState([]); const [正在加载,setLoading] = useState(true); const [错误,setError] = useState(null); 使用效果(()=> { fetch(`${process.env.REACT_APP_API_BASE_URL}用户`) .then(响应=> { if (response.ok) 返回response.json(); 抛出响应; }) .then(json => { 设置用户(json); }) .catch(错误=> { 控制台.错误(错误); 设置错误(错误); }) .finally(() => { 设置加载(假); }); }, []); 如果(正在加载)返回“正在加载...”; 如果(错误)返回“哎呀!”; 返回用户[0].用户名;}

登录后复制

对于一个简单的应用程序,只需提出一些请求,它就应该可以正常工作。但上面的状态声明和useEffect都是模板。如果我要进行多次 HTTP 调用,我不想为每个调用重复并维护大约 20 行代码。内联调用使您的代码看起来很丑陋。

看看我们正在尝试解决的一些问题:

这只是一个简单的例子,忽略了许多其他相关问题。

方法二:文件夹集中管理

如果我们在一个文件夹中处理所有HTTP调用会怎么样?使用这种方法,我们创建一个名为 services 的文件夹,并将所有进行 HTTP 调用的函数放入其中。 服务是最流行的术语,我还在下面讨论了很多好的替代名称,例如clientapi

导出函数getUsers () { 返回 fetch(`${process.env.REACT_APP_API_BASE_URL}users`).then(response => 响应.json() ); }

登录后复制

以下是对getUsers函数的调用:

从“react”导入 React, { useState, useEffect };
从“./services/userService”导入{ getUsers };

导出默认函数 CentralDemo() {
  const [用户,setUsers] = useState([]);
  const [正在加载,setLoading] = useState(true);
  const [错误,setError] = useState(null);
  使用效果(()=> {
    获取用户()
      .then(json => {
        设置用户(json);
        设置加载(假);
      })
      .catch(错误=> {
        控制台.错误(错误);
        设置错误(错误);
      });
  }, []);

  如果(正在加载)返回“正在加载...”;
  如果(错误)返回“哎呀!”;
  返回用户[0].用户名;
}
登录后复制

但这并没有过多简化请求调用。主要好处是它强制对 HTTP 调用进行一致处理。这个想法是这样的:当相关的函数一起处理时,更容易一致地处理它们。如果 userService 文件夹中充满了进行 HTTP 调用的函数,那么我可以轻松确保它们始终如一地执行。此外,如果重复使用调用,则可以轻松地从此集中位置调用它们。

但是,我们可以做得更好。

方法三:自定义Hook

借助React Hooks的魔力,我们终于可以专注于重复的逻辑了。那么,创建一个自定义 useFetch 挂钩来简化我们的 HTTP 调用怎么样?

从“react”导入 { useState, useEffect, useRef };
// 这个自定义挂钩集中并简化了 HTTP 调用的处理
导出默认函数 useFetch(url, init) {
  const [数据,setData] = useState(null);
  const [正在加载,setLoading] = useState(true);
  const [错误,setError] = useState(null);
  const prevInit = useRef();
  const prevUrl = useRef();

  使用效果(()=> {
  // 仅当 url 或 init 参数更改时才重新获取。
    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(响应=> {
        if (response.ok) 返回response.json();
        设置错误(响应);
      })
      .then(数据 => setData(数据))
      .catch(错误=> {
        控制台.错误(错误);
        设置错误(错误);
      })
      .finally(() => setLoading(false));
  }, [init, url]);

  返回{数据,加载,错误};}
登录后复制

您的可能看起来有所不同,但我发现这种基本用法很有帮助。这个 Hook 极大地简化了所有调用。看看使用这个 Hook 需要多少代码:

从“react”导入React;
从“./useFetch”导入useFetch;

导出默认函数 HookDemo() {
  const { 数据,加载,错误 } = useFetch("users");
  如果(正在加载)返回“正在加载...”;
  如果(错误)返回“哎呀!”;
  返回数据[0].用户名;
}
登录后复制

对于许多应用程序,您只需要像这样的自定义Hook。但这个 Hook 已经很复杂了,它消除了很多问题。

但是还有很多点我们没有考虑到:缓存? 。如果客户端的连接不可靠,如何重新获取呢?当用户调整标签大小时,您想重新获取新数据吗?如何消除重复查询?

你可以继续完善这个自定义Hook来完成所有这些操作。然而,你应该只需要方法 4:

方法四:react-query/swr

使用react-query或者swr,它可以为我们处理缓存、重试、重复查询等。我不必维护自己的自定义 Hook。每个 HTTP 调用只需要很少的代码:

从“react”导入React;
从“./services/userService”导入{ getUsers };
从“react-query”导入{useQuery};

导出默认函数 ReactQueryDemo() {
  const { data, isLoading, error } = useQuery("users", getUsers);
  if (isLoading) 返回“正在加载...”;如果(错误)返回“哎呀!”;
  返回数据[0].用户名;
}
登录后复制

这是我今天对于大多数应用程序的首选。完整代码如下:https://www.hack95.com/s/4-ways-to-handle-restful-http-in-react-k3xug,大家可以自己对比一下。

推荐学习:《react视频教程》

以上是react中请求远程数据的四种方法的详细介绍。更多相关内容请关注其他相关文章!