Home  >  Article  >  Web Front-end  >  What are the four methods to request remote data in react

What are the four methods to request remote data in react

青灯夜游
青灯夜游Original
2021-11-30 10:30:572632browse

Four ways to request remote data: 1. Make HTTP calls directly in the React component and process the response; 2. Create a folder, put all the functions that make HTTP calls into it, and centrally request data and process it. Response; 3. Customize Hook to request data; 4. Use "react-query" or swr to request data.

What are the four methods to request remote data in react

The operating environment of this tutorial: Windows7 system, react17.0.1 version, Dell G3 computer.

Four ways to request remote data in React

React is a dedicated component library. Therefore, it has few suggestions on how to request remote data. If you want to request data via HTTP and send it to Web API, here are four methods to consider.

  • Inline writing

  • Centralized management

  • CustomizationHook

  • react-query/swr

Note: In this article, I will use fetch makes HTTP calls, but these patterns also apply to alternatives like Axios. Alternatively, if you are using GraphQ L, there are other good options to consider like Apollo. This article assumes you are calling a traditional REST API.

Method 1: Inline

This is the simplest and most direct option. Make the HTTP call and handle the response in the React component.

fetch("/users").then(response => response.json());

Looks simple. But this example ignores loading status, error handling, declaring and setting related status, etc. In the real world, a HTTP call would look more like this.

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;
}

For a simple application, just make a few requests and it will work fine. But the above state declaration and useEffect are both templates. If I'm going to make many HTTP calls, I don't want to repeat and maintain about 20 lines of code for each call. Inline calls make your code look ugly.

Look at some of the issues we want to solve:

  • Declare loading status

  • Declare error status

  • Print the error to the console

  • Check if the response passes and return 200 response.ok

  • If the response is OK, convert the response to json and return promise

  • If the response is incorrect, throw an error

  • Hide the loading state in finally to ensure that Loading is hidden even if an error occurs

  • ##State a Empty dependency array so that

    useEffect only runs once

This is just a simple example that ignores many other related issues.

Method 2: Folder centralized management

What if we handle all

HTTP calls in one folder? Using this method, we create Create a folder named services and put all the functions that make HTTP calls into it. service is the most popular term, I have also discussed a lot of good alternative names below such as client or api.

What are the four methods to request remote data in react

The main point is that all

HTTP calls are handled through pure JavaScript functions, stored in a folder. This is a centralized getUsers function:

export function getUsers() {
  return fetch(`${process.env.REACT_APP_API_BASE_URL}users`).then(response =>
    response.json()
  );
}

Here is the call to the

getUsers function:

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;
}

However this does not simplify the request call too much . The main benefit is that it enforces consistent handling of

HTTP calls. The idea is this: when related functions are processed together, it's easier to process them consistently. If the userService folder is full of functions making HTTP calls, I can easily make sure they do so consistently. Additionally, if calls are reused, they are easily invoked from this centralized location.

However, we can do better.

Method 3: Custom Hook

With the magic of

React Hooks, we can finally focus on processing repetitive logic. So how do we create a custom useFetch hook to simplify our HTTP calls?

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 };
}

Yours may look different, but I find this basic usage helpful. This Hook greatly simplifies all calls. Look at how much code it takes to use this

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;
}

For many applications, you only need one custom Hook like this. But this Hook is already complex, and it eliminates many problems.

But there are still many points that we have not considered: caching? . If the client's connection is unreliable, how to obtain it again? Do you want to re-fetch new data when the user resizes the label? How to eliminate duplicate queries?

You can continue to improve this custom Hook to complete all these operations. However, you should only need way 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,你可以自己进行比较。

推荐学习:《react视频教程

The above is the detailed content of What are the four methods to request remote data in react. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn