• Start by implementing your own API Client
    • Regardless of the size of the project, first create your own API Client through which all subsequent requests are sent
    • You can do some general configuration and processing on the server to be connected in the API Client, such as Token, URL, error handling, etc
// Axios has a more convenient, semantic API than FETCH

import axios from 'axios'

// Define the associated endpoint

const endPoints = {

    test: "https://.... /".prod: "https://... /"

}


// Create an instance of Axios

const instance = axios.create({

    baseURL: endPoints.test,

    timeout: 3000.// Set a common header for all requests

    headers: { Authorization: "Bear mytoken"}})// An interceptor is defined through AXIos to process all requests

instance.interceptors.response.use(

    (res) = > {

        // Some logic to request success

        return res

    },

    (err) = > {

        if (err.response.status === 403) {

            // Unauthorised requests are processed and the login page is displayed

            document.location = '/login'

        }

        return Promise.reject(err)

    }

)

export default instance
Copy the code
  • Think about asynchronous requests using Hooks

The essence of Hooks is that everything is hooked, that is, we can turn any data source into a data source that can be bound to the React component.

For an API of type GET, we can think of it as a remote resource. Unlike local data, it has three states:

  1. Data: Refers to the Data returned by the server after a successful request;
  2. Error: If the request fails, the Error message will be displayed in the Error state.
  3. Pending: A request is sent and is in a Pending state until it is returned.

Encapsulate the API for retrieving articles as a remote resource Hook

import { useState, useEffect } from 'react'

import apiClient from './apiClient'

const useArticle = (id) = > {

    const [data,setDate] = useState(null)

    const [loading,setLoading] = useState(false)

    const [error,setError] = useState(null)

  
    useEffect(() = > {

        setLoading(true)

        setError(null)

        setData(null)

        
        apiClient.get(`/getArticle/${id}`)

                .then((res) = > {

                    setData(res.data)

                    setLoading(false)

                })

                .catch((err) = > {

                    setError(err)

                    setLoading(false)

                })

    },[id])


    // Take three states as the return values of Hook

    // The three states of the remote data

    reuturn {

        loading,

        error,

        data

    }
}
Copy the code

So instead of displaying an article as a concrete API call, you can think of it as remote data.

import useArticle from './useArticle'

const ArticleView = ({ id }) = > {

    const { data, loading, error } = useArticle(id)

    if (error) return 'Failed'

    if(! data || loading)return 'Loading... '

    return (

        <div>

            // ...

        </div>)}Copy the code

In a project, you can make each Get request one of these hooks. Data requests and processing logic are put in Hooks to isolate Model and View.

Why not provide a generic Hook and pass in the API address?

In fact, it can be written separately to ensure that each Hook is simple enough on its own. In general, further processing is usually required in order for the data returned by the server to meet the presentation requirements on the UI.

  • Multiple API calls: How are concurrent or serial requests handled?

As a complete page, for example, you need to send three requests:

  1. Get article content
  2. Get author information, including name and avatar address
  3. Get a list of comments for the article

These three requests contain both concurrent and serial scenarios: article content and article comment lists can be requested concurrently, using the same article ID. And the author information needs to return the article information, according to the article information to request the author information, is a serial scenario.

The traditional way to do it is:

const [article, comments] = await Promise.all([

    fetchArticle(articleId),

    fetchComments(articleId)

])

const author = await fetchAuthor(article.userId)
Copy the code

Different from the above, useEffect is added to determine whether there is a useEffect

So, on the presentation page of the article