SoFunction
Updated on 2025-03-09

Detailed explanation of how to request data in React using Axios

This article mainly contains the following content:

  • useaxiosConduct simple data acquisition
  • Add state variables to optimize interactive experience
  • CustomizehookPerform data acquisition
  • useuseReducerRenovation request

The main focus is 134 points! This article is mainly suitable forBeginners who are new to ReactAnd don't know how to regulate itReactthe person who gets the data.

Precondition: First prepare a backend interface, and the code is as follows:

@GetMapping("")
public Map<String,Object> getListData(Integer size) {
    if ((size)){
        size = 10;
    }
    List<Student> resultList = new ArrayList<>();
    for (int i = 1; i <= size; i++) {
        Student student = new Student();
        (i);
        ((int) (() * 100));
        (().toString().split("-")[0]);
        (student);
    }
    Map<String, Object> hashMap = new HashMap<>();
    ("data",resultList);
    ("status",200);
    return hashMap;
}

Front-end adoptionreact 18.2 + axiosConstruct the environment! After successfully setting up the environment, delete itThe code after deletion is as follows:

import { useState } from 'react'
import './'
import axios from 'axios'
​
function App() {
  return (
    <>
      <div>
      </div>
    </>
  )
}
​
export default App

Simple data acquisition using axios

Modify firstThe code is as follows:

function App() {
  const [data, setData] = useState({
    data: []
  })
  return (
    <>
      <div>
        student name
        <ul>
          {
            (student =>{
              return (
                <li key={}>
                  {}
                </li>
              )
            })
          }
        </ul>
      </div>
    </>
  )
}

First of all, useuseEffectTo obtain data, you need to pay attention to this step:

  • useEffect()The arrow function inasyncModification.
  • useEffect()The second parameter problem

First of all, inAdd the following code to

useEffect(async () => {
    const result = await axios("http://127.0.0.1:8080/student/")
    setData()
})

At this time, the project cannot run normally, and the following error message will appear:

:86 Warning: useEffect must not return anything besides a function, which is used for clean-up.

It looks like you wrote useEffect(async () => ...) or returned a Promise. Instead, write the async function inside your effect and call it immediately:

useEffect(() => { async function fetchData() { // You can await here const response = await (someId); // ... } fetchData(); }, [someId]); // Or [] if effect doesn't need props or state

Therefore, according to the error message, we need to modify our writing method as follows:

useEffect(() => {
    const fetchData = async () => {
        const result = await axios("http://127.0.0.1:8080/student/")
        setData()
    }
    fetchData();
})

After this modification, the project can run normally! The page can display data normally! But you must have found the following problems:stuNameAlways changing. This is because in useuseEffectWhen performing data acquisition, if no second parameter is specified, that is, its dependency,useEffectEvery time the render runs, it leads touseEffectinfinite loop.

So at this time we can add the second parameter, the code is as follows.

useEffect(() => {
    const fetchData = async () => {
        const result = await axios("http://127.0.0.1:8080/student/")
        setData()
    }
    fetchData();
},[])

Passing an empty array representation, without any dependencies, i.e.mountedThis method will not be triggered later.

If we need to rely on a certain parameter, that is, after a certain parameter changes, we need to reload the data, and then combine the parameters in the backend interfacesize,existAdd the following code to:

const [size,setSize] = useState(5)
​
useEffect(() =&gt; {
    const fetchData = async () =&gt; {
        const result = await axios(`http://127.0.0.1:8080/student/?size=${size}`)
        setData()
    }
    fetchData();
}, [size])
​
&lt;div&gt;
      student name
          &lt;input
            type='number'
            value={size}
            onChange={event =&gt; setSize()}
            /&gt;
    &lt;ul&gt;
     Omit other codes
    &lt;/ul&gt;
​
&lt;/div&gt;

At this time, when we enter numbers in the input box, we will find the content changes. However, there are other problems with this. Whenever we enter a number, the effect of one-digit number is not obvious. When entering a 3-digit or 4-digit number, every time we enter a character, it will issue an http request. To obtain data, obviously this is not the effect we want. Therefore, it can be triggered manually instead, the code is as follows:

function App() {
​
  const [size, setSize] = useState(5)
  const [query, setQuery] = useState('')
  const [data, setData] = useState({
    data: []
  })
​
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(`http://127.0.0.1:8080/student/?size=${size}`)
      setData()
    }
    fetchData();
  }, [query])
​
  return (
    <>
      <div>
        student name
        <input
          type='number'
          value={size}
          onChange={event => setSize()}
        />
        <button onClick={() => setQuery(size)} >click me</button>
        <ul>
          {
            (student => {
              return (
                <li key={}>
                  {}
                </li>
              )
            })
          }
        </ul>
      </div>
    </>
  )
}

This can be triggered by manually clicking the query! But there are still some ways to optimize this method.queryandsizeBoth state variables are used to trigger the query function, andquerythat issizeA copy of the , which can therefore be simplified to the following:

​
function App() {
  const [size, setSize] = useState(5)
  const [url,setUrl] = useState('http://127.0.0.1:8080/student/?size=5')
  const [data, setData] = useState({
    data: []
  })
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(url)
      setData()
    }
    fetchData();
  }, [url])
  return (
    <>
      <div>
        student name
        <input
          type='number'
          value={size}
          onChange={event => setSize()}
        />
        <button onClick={() => setUrl(`http://127.0.0.1:8080/student/?size=${size}`)} >click me</button>
        <ul>
          {
            (student => {
              return (
                <li key={}>
                  {}
                </li>
              )
            })
          }
        </ul>
      </div>
    </>
  )
}

At this point, the simple data request is over! If it's just for the purpose of getting data, then that's the end!

Add state variables to optimize data loading process

Anyone who has written vue should knowelement-plusIn-housetableAll components have oneloadingConfiguration item, used to display the current data acquisition status when making a data request. This is the effect achieved in this part!

const [isLoading, setIsLoading] = useState(false)
//Omit other codes that have not been changeduseEffect(() =&gt; {
    const fetchData = async () =&gt; {
        setIsLoading(true)
        const result = await axios(url)
        setData()
        setIsLoading(false)
    }
    fetchData();
}, [url])
{
    isLoading ? (&lt;div&gt;Data is loading...&lt;/div&gt;) : (
        &lt;ul&gt;
            {
                (student =&gt; {
                    return (
                        &lt;li key={}&gt;
                            {}
                        &lt;/li&gt;
                    )
                })
            }
        &lt;/ul&gt;
    )
}

Then in ourJavaAdd a delay code to the code:

try {
    (5);
} catch (InterruptedException e) {
    ();
}

After restarting the project, every request page after this will display a data loading process!

In addition to displaying the loading process of data, we can also add exception handling: the code is as follows, omitting other unchanged codes!

const [errorInfo,setErrorInfo] = useState({
    isError:false,
    message:''
})
useEffect(() =&gt; {
    const fetchData = async () =&gt; {
        setIsLoading(true)
​
        setErrorInfo({
            isError:false,
            message:"no error",
        })
        try {
            const result = await axios(url)
            setData()
        } catch (error) {
            setErrorInfo({
                isError:true,
                message:
            })
        }
        setIsLoading(false)
    }
    fetchData();
}, [url])
​
{  &amp;&amp; (&lt;div&gt;Data loading error: {}&lt;/div&gt;) }

Custom hook for data acquisition

In the above code, we have written all the code in the samejsxIn the file, this is not conducive to our code maintenance [Imagine there are many state variables, how big is this file! 】; Therefore, it is necessary to extract the logic of the data request and put it into the newly createdIn the file, the code looks like this:

​// 
import { useEffect, useState } from 'react'
import axios from 'axios'
export const loadStudentList = (initUrl, initData) => {
​
    const [url, setUrl] = useState(initUrl)
    const [data, setData] = useState(initData)
    const [isLoading, setIsLoading] = useState(false)
    const [errorInfo, setErrorInfo] = useState({
        isError: false,
        message: ''
    })
​
    useEffect(() => {
        const fetchData = async () => {
            setIsLoading(true)
            setErrorInfo({
                isError: false,
                message: "no error",
            })
            try {
                const result = await axios(url)
                setData()
            } catch (error) {
                setErrorInfo({
                    isError: true,
                    message: 
                })
            }
            setIsLoading(false)
        }
        fetchData();
    }, [url])
    return [{ data, isLoading, errorInfo }, setUrl];
} 
​

at this timeThe code is as follows:

function App() {
​
  const [size,setSize] = useState(5)
  const [{data,isLoading,errorInfo}, doFetch] = loadStudentList('http://127.0.0.1:8080/student/?size=5',{
    data:[]
  }) 
  return (
    &lt;&gt;
      &lt;div&gt;
        student name
        &lt;input
          type='number'
          value={size}
          onChange={event =&gt; setSize()}
        /&gt;
        &lt;button onClick={() =&gt; doFetch(`http://127.0.0.1:8080/student/?size=${size}`)} &gt;click me&lt;/button&gt;
​
        {  &amp;&amp; (&lt;div&gt;Data loading error: {}&lt;/div&gt;) }
        {
          isLoading ? (&lt;div&gt;Data is loading...&lt;/div&gt;) : (
            &lt;ul&gt;
              {
                (student =&gt; {
                  return (
                    &lt;li key={}&gt;
                      {}
                    &lt;/li&gt;
                  )
                })
              }
            &lt;/ul&gt;
          )
        }
      &lt;/div&gt;
    &lt;/&gt;
  )
}

This makes it much easier to compare before and after. Even if there are many data interfaces behind it, the contents of this file will not be too much! It's basically over here! But we can still use ituseReducerFurther optimize our requests!

Optimization with useReducer

In the above codeerrorInfo,isLoadingThey are related, but are maintained separately, so in order to aggregate them together, you can use reducers for optimization:

​
import { useEffect, useState, useReducer } from 'react'
import axios from 'axios'
​
const dataFetchReducer = (state, action) => {
    switch () {
        case 'FETCH_INIT':
            return {
                ...state,
                isLoading: true,
                errorInfo: {
                    isError:false,
                    message:'',
                }
            };
        case 'FETCH_SUCCESS':
            return {
                ...state,
                isLoading: false,
                errorInfo: {
                    isError:false,
                    message:'',
                },
                data: ,
            };
        case 'FETCH_FAILURE':
            return {
                ...state,
                isLoading: false,
                errorInfo: {
                    isError:true,
                    message:,
                }
            };
        default:
            throw new Error();
    }
}
​
export const loadStudentList = (initUrl, initData) => {
    const [url, setUrl] = useState(initUrl)
    const [state, dispatch] = useReducer(dataFetchReducer, {
        isLoading: false,
        errorInfo: {
            isError: false,
            message: ''
        },
        data: initData,
    });
    useEffect(() => {
        const fetchData = async () => {
            dispatch({ type: 'FETCH_INIT' });
            try {
                const result = await axios(url)
                dispatch({ type: 'FETCH_SUCCESS', payload:  });
            } catch (error) {
                dispatch({ type: 'FETCH_FAILURE',payload:error });
            }
            // setIsLoading(false)
        }
        fetchData();
    }, [url])
​
    return [state, setUrl]
}
​

The above is a detailed explanation of the method of using Axios to request data in React. For more information about Axios requesting data in React, please pay attention to my other related articles!