最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Axios在React中請求數(shù)據(jù)的方法詳解

 更新時間:2023年09月24日 09:06:13   作者:Supersist  
這篇文章主要給大家介紹了初學React,如何規(guī)范的在react中請求數(shù)據(jù),主要介紹了使用axios進行簡單的數(shù)據(jù)獲取,加入狀態(tài)變量,優(yōu)化交互體驗,自定義hook進行數(shù)據(jù)獲取和使用useReducer改造請求,本文主要適合于剛接觸React的初學者以及不知道如何規(guī)范的在React中獲取數(shù)據(jù)的人

本文主要有以下內容:

  • 使用axios進行簡單的數(shù)據(jù)獲取
  • 加入狀態(tài)變量,優(yōu)化交互體驗
  • 自定義hook進行數(shù)據(jù)獲取
  • 使用useReducer改造請求

重點主要在134點! 本文主要適合于剛接觸React的初學者以及不知道如何規(guī)范的在React中獲取數(shù)據(jù)的人。

前置條件:首先準備一個后端接口,其代碼如下:

@GetMapping("list.do")
public Map<String,Object> getListData(Integer size) {
 ? ?if (Objects.isNull(size)){
 ? ? ? ?size = 10;
 ?  }
 ? ?List<Student> resultList = new ArrayList<>();
 ? ?for (int i = 1; i <= size; i++) {
 ? ? ? ?Student student = new Student();
 ? ? ? ?student.setStuId(i);
 ? ? ? ?student.setAge((int) (Math.random() * 100));
 ? ? ? ?student.setStuName(UUID.randomUUID().toString().split("-")[0]);
 ? ? ? ?resultList.add(student);
 ?  }
 ? ?Map<String, Object> hashMap = new HashMap<>();
 ? ?hashMap.put("data",resultList);
 ? ?hashMap.put("status",200);
 ? ?return hashMap;
}

前端采用react 18.2 + axios進行環(huán)境搭建!在成功搭建環(huán)境后,刪除掉App.jsx中的無關代碼,刪除后的代碼如下:

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

使用axios進行簡單的數(shù)據(jù)獲取

首先修改App.jsx代碼如下:

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

首先是使用useEffect進行數(shù)據(jù)獲取,在這一步需要注意如下:

  • useEffect()中的箭頭函數(shù)不能被async修飾。
  • useEffect()的第二個參數(shù)的問題

首先是第一點,在app.jsx中添加如下代碼

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

此時項目不能夠正常運行,項目會出現(xiàn)如下的報錯信息:

react-dom.development.js: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 MyAPI.getData(someId); // ... } fetchData(); }, [someId]); // Or [] if effect doesn't need props or state

因此根據(jù)錯誤信息,需要修改我們的寫法如下:

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

這樣修改之后,項目可以正常運行了!頁面可以正常顯示數(shù)據(jù)了!但是細心的你一定發(fā)現(xiàn)了如下問題:stuName一直在變化。這是因為在使用useEffect進行數(shù)據(jù)獲取時,如果沒有指定第二個參數(shù),即他的依賴,則useEffect在每一次render都會運行,因此就導致了useEffect的無限循環(huán)。

所以此時我們添加第二個參數(shù)即可,代碼如下。

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

傳遞空數(shù)組表示,沒有任何依賴,即在mounted后將不會觸發(fā)該方法。

如果說當我們需要依賴某個參數(shù)時,即某個參數(shù)發(fā)生改變后,我們需要重新加載數(shù)據(jù),此時結合后端接口中的參數(shù)size,在App.jsx中添加如下代碼:

const [size,setSize] = useState(5)
?
useEffect(() => {
 ? ?const fetchData = async () => {
 ? ? ? ?const result = await axios(`http://127.0.0.1:8080/student/list.do?size=${size}`)
 ? ? ? ?setData(result.data)
 ?  }
 ? ?fetchData();
}, [size])
?
<div>
 ? ? ?student name
 ? ? ? ? ?<input
 ? ? ? ? ? ?type='number'
 ? ? ? ? ? ?value={size}
 ? ? ? ? ? ?onChange={event => setSize(event.target.value)}
 ? ? ? ? ? ?/>
    <ul>
 ? ? 省略其他代碼
 ? ?</ul>
?
</div>

此時當我們在輸入框輸入數(shù)字時,就會發(fā)現(xiàn)內容的改變。但是這樣存在了其他問題,每當我們輸入一個數(shù)時,一位數(shù)效果不明顯,在輸入3位數(shù)或者4位數(shù)時,每輸入一個字符,他都會發(fā)出一個http請求。進行數(shù)據(jù)獲取,顯然這不是我們要的效果。因此就可以改為手動觸發(fā),代碼如下:

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/list.do?size=${size}`)
 ? ? ?setData(result.data)
 ?  }
 ? ?fetchData();
  }, [query])
?
 ?return (
 ? ?<>
 ? ? ?<div>
 ? ? ?  student name
 ? ? ? ?<input
 ? ? ? ? ?type='number'
 ? ? ? ? ?value={size}
 ? ? ? ? ?onChange={event => setSize(event.target.value)}
 ? ? ? ?/>
 ? ? ? ?<button onClick={() => setQuery(size)} >click me</button>
 ? ? ? ?<ul>
 ? ? ? ?  {
 ? ? ? ? ? ?data.data.map(student => {
 ? ? ? ? ? ? ?return (
 ? ? ? ? ? ? ? ?<li key={student.stuId}>
 ? ? ? ? ? ? ? ?  {student.stuName}
 ? ? ? ? ? ? ? ?</li>
 ? ? ? ? ? ?  )
 ? ? ? ? ?  })
 ? ? ? ?  }
 ? ? ? ?</ul>
 ? ? ?</div>
 ? ?</>
  )
}

這樣就可以通過手動點擊查詢的方式觸發(fā)!但這種方式還有可以優(yōu)化的地方,querysize這兩個狀態(tài)變量都用于觸發(fā)查詢功能,且query就是size的一個復制,因此可以簡化為如下:

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

到這一步簡單的數(shù)據(jù)請求就結束了!如果只是為了獲取數(shù)據(jù),則到此就結束了!

加入狀態(tài)變量,優(yōu)化數(shù)據(jù)加載過程

寫過vue的都應該了解過在element-plus中的table組件都有一個loading配置項,當進行數(shù)據(jù)請求時,用于顯示當前的數(shù)據(jù)獲取狀態(tài)。這一部分實現(xiàn)的效果就是如此!

const [isLoading, setIsLoading] = useState(false)
// 省略沒有改變的其他代碼
useEffect(() => {
 ? ?const fetchData = async () => {
 ? ? ? ?setIsLoading(true)
 ? ? ? ?const result = await axios(url)
 ? ? ? ?setData(result.data)
 ? ? ? ?setIsLoading(false)
 ?  }
 ? ?fetchData();
}, [url])
{
 ? ?isLoading ? (<div>數(shù)據(jù)加載中...</div>) : (
 ? ? ? ?<ul>
 ? ? ? ? ?  {
 ? ? ? ? ? ? ? ?data.data.map(student => {
 ? ? ? ? ? ? ? ? ? ?return (
 ? ? ? ? ? ? ? ? ? ? ? ?<li key={student.stuId}>
 ? ? ? ? ? ? ? ? ? ? ? ? ?  {student.stuName}
 ? ? ? ? ? ? ? ? ? ? ? ?</li>
 ? ? ? ? ? ? ? ? ?  )
 ? ? ? ? ? ? ?  })
 ? ? ? ? ?  }
 ? ? ? ?</ul>
 ?  )
}

然后在我們的Java代碼中添加一個延時代碼:

try {
 ? ?TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
 ? ?e.printStackTrace();
}

重新啟動項目之后,在這之后的每一次請求頁面就會顯示一個數(shù)據(jù)的加載過程!

除了顯示數(shù)據(jù)的加載過程,我們還可以添加異常處理:代碼如下,省略了其他沒有改變的代碼!

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(result.data)
 ? ? ?  } catch (error) {
 ? ? ? ? ? ?setErrorInfo({
 ? ? ? ? ? ? ? ?isError:true,
 ? ? ? ? ? ? ? ?message:error.message
 ? ? ? ? ?  })
 ? ? ?  }
 ? ? ? ?setIsLoading(false)
 ?  }
 ? ?fetchData();
}, [url])
?
{ errorInfo.isError && (<div>數(shù)據(jù)加載出錯: {errorInfo.message}</div>) }

自定義hook進行數(shù)據(jù)獲取

在上面的代碼中,我們都是將所有的代碼寫在了同一個jsx文件里面,這樣不利于我們進行代碼維護【想象一下有很多很多的狀態(tài)變量,這個文件得多大!】;因此需要將數(shù)據(jù)請求的邏輯提取出來放入至新建的request.js文件中,代碼如下所示:

?// request.js
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(result.data)
 ? ? ? ? ?  } catch (error) {
 ? ? ? ? ? ? ? ?setErrorInfo({
 ? ? ? ? ? ? ? ? ? ?isError: true,
 ? ? ? ? ? ? ? ? ? ?message: error.message
 ? ? ? ? ? ? ?  })
 ? ? ? ? ?  }
 ? ? ? ? ? ?setIsLoading(false)
 ? ? ?  }
 ? ? ? ?fetchData();
 ?  }, [url])
 ? ?return [{ data, isLoading, errorInfo }, setUrl];
} 
?

此時App.jsx的代碼如下所示:

function App() {
?
 ?const [size,setSize] = useState(5)
 ?const [{data,isLoading,errorInfo}, doFetch] = loadStudentList('http://127.0.0.1:8080/student/list.do?size=5',{
 ? ?data:[]
  }) 
 ?return (
 ? ?<>
 ? ? ?<div>
 ? ? ?  student name
 ? ? ? ?<input
 ? ? ? ? ?type='number'
 ? ? ? ? ?value={size}
 ? ? ? ? ?onChange={event => setSize(event.target.value)}
 ? ? ? ?/>
 ? ? ? ?<button onClick={() => doFetch(`http://127.0.0.1:8080/student/list.do?size=${size}`)} >click me</button>
?
 ? ? ?  { errorInfo.isError && (<div>數(shù)據(jù)加載出錯: {errorInfo.message}</div>) }
 ? ? ?  {
 ? ? ? ? ?isLoading ? (<div>數(shù)據(jù)加載中...</div>) : (
 ? ? ? ? ? ?<ul>
 ? ? ? ? ? ?  {
 ? ? ? ? ? ? ? ?data.data.map(student => {
 ? ? ? ? ? ? ? ? ?return (
 ? ? ? ? ? ? ? ? ? ?<li key={student.stuId}>
 ? ? ? ? ? ? ? ? ? ?  {student.stuName}
 ? ? ? ? ? ? ? ? ? ?</li>
 ? ? ? ? ? ? ? ?  )
 ? ? ? ? ? ? ?  })
 ? ? ? ? ? ?  }
 ? ? ? ? ? ?</ul>
 ? ? ? ?  )
 ? ? ?  }
 ? ? ?</div>
 ? ?</>
  )
}

這樣前后一對比,就簡化了很多很多。即使后面有再多的數(shù)據(jù)接口按照這種方式,這個文件的內容也不會太多!到這里基本上就可以結束了!不過我們還可以使用useReducer 進一步優(yōu)化我們的請求!

使用useReducer優(yōu)化

在上面的代碼中errorInfo,isLoading他們是相關的,但是卻是分別維護的,因此為了讓其聚合在一起可采用reducer進行優(yōu)化:

?
import { useEffect, useState, useReducer } from 'react'
import axios from 'axios'
?
const dataFetchReducer = (state, action) => {
 ? ?switch (action.type) {
 ? ? ? ?case 'FETCH_INIT':
 ? ? ? ? ? ?return {
 ? ? ? ? ? ? ? ?...state,
 ? ? ? ? ? ? ? ?isLoading: true,
 ? ? ? ? ? ? ? ?errorInfo: {
 ? ? ? ? ? ? ? ? ? ?isError:false,
 ? ? ? ? ? ? ? ? ? ?message:'',
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  };
 ? ? ? ?case 'FETCH_SUCCESS':
 ? ? ? ? ? ?return {
 ? ? ? ? ? ? ? ?...state,
 ? ? ? ? ? ? ? ?isLoading: false,
 ? ? ? ? ? ? ? ?errorInfo: {
 ? ? ? ? ? ? ? ? ? ?isError:false,
 ? ? ? ? ? ? ? ? ? ?message:'',
 ? ? ? ? ? ? ?  },
 ? ? ? ? ? ? ? ?data: action.payload,
 ? ? ? ? ?  };
 ? ? ? ?case 'FETCH_FAILURE':
 ? ? ? ? ? ?return {
 ? ? ? ? ? ? ? ?...state,
 ? ? ? ? ? ? ? ?isLoading: false,
 ? ? ? ? ? ? ? ?errorInfo: {
 ? ? ? ? ? ? ? ? ? ?isError:true,
 ? ? ? ? ? ? ? ? ? ?message:action.payload.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: result.data });
 ? ? ? ? ?  } catch (error) {
 ? ? ? ? ? ? ? ?dispatch({ type: 'FETCH_FAILURE',payload:error });
 ? ? ? ? ?  }
 ? ? ? ? ? ?// setIsLoading(false)
 ? ? ?  }
 ? ? ? ?fetchData();
 ?  }, [url])
?
 ? ?return [state, setUrl]
}
?

以上就是使用Axios在React中請求數(shù)據(jù)的方法詳解的詳細內容,更多關于Axios在React中請求數(shù)據(jù)的資料請關注腳本之家其它相關文章!

相關文章

  • react-native-tab-navigator組件的基本使用示例代碼

    react-native-tab-navigator組件的基本使用示例代碼

    本篇文章主要介紹了react-native-tab-navigator組件的基本使用示例代碼,具有一定的參考價值,有興趣的可以了解一下
    2017-09-09
  • 在React中寫一個Animation組件為組件進入和離開加上動畫/過度效果

    在React中寫一個Animation組件為組件進入和離開加上動畫/過度效果

    這篇文章主要介紹了在React中寫一個Animation組件為組件進入和離開加上動畫/過度效果,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • React18的useEffect執(zhí)行兩次如何應對

    React18的useEffect執(zhí)行兩次如何應對

    這篇文章主要給大家介紹了關于React18的useEffect執(zhí)行兩次如何應對的相關資料,文中通過實例代碼介紹的非常詳細,對大家學習或者使用React具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • React系列useSyncExternalStore學習詳解

    React系列useSyncExternalStore學習詳解

    這篇文章主要為大家介紹了React系列useSyncExternalStore的學習及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • react無限滾動組件的實現(xiàn)示例

    react無限滾動組件的實現(xiàn)示例

    本文主要介紹了react無限滾動組件的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-05-05
  • React Electron生成桌面應用過程

    React Electron生成桌面應用過程

    這篇文章主要介紹了React+Electron快速創(chuàng)建并打包成桌面應用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-12-12
  • react Input組件Compositionstart和Compositionend事件

    react Input組件Compositionstart和Compositionend事件

    這篇文章主要為大家介紹了Compositionstart和Compositionend事件之于react組件庫Input組件的坑解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • React html中使用react的兩種方式

    React html中使用react的兩種方式

    這篇文章主要介紹了React html中使用react的兩種方式,本文給大家提到了React pwa的配置代碼,給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • React jsx轉換與createElement使用超詳細講解

    React jsx轉換與createElement使用超詳細講解

    這篇文章主要介紹了React jsx轉換與createElement使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-11-11
  • ReactRouterV6如何獲取當前路由參數(shù)

    ReactRouterV6如何獲取當前路由參數(shù)

    這篇文章主要介紹了ReactRouterV6如何獲取當前路由參數(shù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03

最新評論

隆子县| 巢湖市| 阳曲县| 拜城县| 太湖县| 广南县| 孟村| 鸡东县| 乐业县| 香格里拉县| 额济纳旗| 广宁县| 安仁县| 莒南县| 孝感市| 许昌县| 宝清县| 昌江| 吴旗县| 昌吉市| 丰顺县| 海城市| 靖州| 阿坝县| 嘉定区| 保亭| 郴州市| 洮南市| 玛纳斯县| 吴川市| 东港市| 湘潭县| 虎林市| 紫金县| 维西| 兴化市| 龙陵县| 江山市| 恩平市| 石嘴山市| 松溪县|