React基础-React中发送Ajax请求以及Mock数据
前言
在?React?中,?render?函數(shù)返回的結(jié)果,取決于組件的?props?和?state
我們都知道?UI?頁面上的數(shù)據(jù)不是寫死的,往往是從后端的數(shù)據(jù)接口中拿到的
然后將真實的數(shù)據(jù)填充到頁面上?,那么應(yīng)該在哪個生命周期函數(shù)中發(fā)起請求?
又如何發(fā)起?Ajax?請求呢以及有哪些方式??以及我們怎么樣模擬一個后端數(shù)據(jù)接口?
示例?API?返回如下?json?對象
假如后端返回的商品列表如下所示
{"goodLists": [{"id": 1, "name": "瓜子", "price": 10, "address": "廣東"},{"id": 2, "name": "蘋果", "price": 20, "address": "北京"},{"id": 3, "name": "橘子", "price": 8, "address": "湖南"},{"id": 4, "name": "桃子", "price": 13, "address": "北京"},{"id": 5, "name": "榴蓮", "price": 18, "address": "海南"}]}把這段商品列表的?json?代碼命名為?goodlist.json?,放到根目錄?public?的?api?文件夾內(nèi)
在?public?目錄下的?api?文件夾下都可以放置你自己模擬的數(shù)據(jù),該模擬的數(shù)據(jù)文件只能放置在?public?目錄下,否則就會報錯,不生效的
對應(yīng)的?UI?效果顯示:如下所示
當(dāng)然對于?UI?以什么樣的方式來顯示,你自己可以用?css?進行控制的,這并不是文本的重點
在哪個生命周期函數(shù)中發(fā)送?AJax?請求
把?Ajax?請求放在?componentWillMount?組件即將被掛載的函數(shù)中也是可以的
但是官方推薦放在?componentDidMount?這個生命周期函數(shù)中發(fā)起?Ajax?請求,因為執(zhí)行這個生命周期時,?DOM?已經(jīng)掛載完了
這樣做可以拿到?Ajax?請求返回的數(shù)據(jù)并通過?setState?來更新組件
componentDidMount(){// 在這里進行Ajax數(shù)據(jù)請求,axios,fetch,jquery Ajax或者request都可以}如何發(fā)送?AJax?請求?
在?React?中,你可以使用你喜歡的?Ajax?庫,例如:?Axios?,瀏覽器內(nèi)置的?feach?方法,?JQuery?Ajax?,或是第三方庫?request?,下面就逐一來看看的
- 方式一使用?Axios?發(fā)送?Ajax?請求
該方式無論是?Vue?還是?React?甚至其他一些框架中,都普遍常用,它支持?promise?方式,在使用?axios?庫之前,應(yīng)該先在終端下使用?npm?或者?cnpm?全局安裝一下
npm install -S axios或者cnpm install -S axios或者yarn add axios安裝完?axios?后,在需要使用請求數(shù)據(jù)的文件最上面,引入?axios?庫,如下代碼所示,下面是上面示例?API?的具體代碼
import React, { Fragment, Component } from 'react';import ReactDOM from 'react-dom';import axios from 'axios'; // 引入axios庫import './style.css';class List extends Component {constructor(props) {super(props);this.baseUrl = '/api/goodlist'; // 這里是本地模擬,在public下創(chuàng)建一個api文件,放置一個json文件,這里的路徑直接是根路徑即可,react會自動的找到這個目錄// this.baseUrl = 'http://localhost:4000/api/goodlist'; // 這種方式是使用代理的方式,這里用的是mockoon工具// this.baseUrl = 'https://easy-mock.com/mock/5b24e12cf076d94c646a9aa2/api/googlists'; //這是使用easy-mockthis.state = {list: [],};}render() {const { list } = this.state;return (<Fragment><ul>{list.map((item) => {const isRed = item.price >= 10 ? 'red' : '';return (<li key={item.id}>{item.name}-<span className={isRed}>{item.price}¥</span>-{item.address}</li>);})}</ul></Fragment>);}// Ajax請求放在componentDidMount生命周期內(nèi)componentDidMount() {// 使用axios完成ajax數(shù)據(jù)請求axios.get(this.baseUrl).then((res) => {const { goodlists } = res.data;this.setState({list: goodlists,});}).catch((err) => {console.log(err);});}}const container = document.getElementById('root');ReactDOM.render(<List />, container);上面的代碼就是在?componentDidMount?中發(fā)起?Ajax?請求,用?axios?請求數(shù)據(jù)
拿到數(shù)據(jù)后,然后通過?setState?去更新組件的?state?的數(shù)據(jù)渲染到頁面上
同時,當(dāng)價格大于?10?時,進行了一些邏輯判斷,讓價格大于?10?的變紅色,在?JSX?里面是可以插值表達式的方式進行一些特殊處理的
注意:本地模擬數(shù)據(jù)的?json?文件(這里是?goodlist.json?),放置的位置只能是放置在根目錄?public?目錄文件夾下,若放置在其他處,是不起作用的
之所以放在?public?能起作用,訪問的路徑直接是根路徑即可,?webpack?做了一些處理,?react?會自動的找到這個目錄
- 方式二:使用瀏覽器內(nèi)置的?fetch?方法
該方法是瀏覽器標(biāo)準(zhǔn)的一個接口,提供了一種簡單合理的方式來跨網(wǎng)絡(luò)異步的獲取資源數(shù)據(jù),現(xiàn)在也是越來越流行使用的,同樣?Ajax?請求也是放在?componentDidMount?組件掛載完之后進行數(shù)據(jù)請求,如下代碼所示
componentDidMount(){// 使用fetch,這里的地止換成上面的this.baseUrl也是可以的fetch('/api/goodlist').then(res => res.json()).then((result) => {console.log(result);const { goodlists } = result;this.setState({list: goodlists})},// 注意在這里處理錯誤時,與axios有些區(qū)別,不是用catch()去捕獲錯誤,因為使用catch去捕獲異常會掩蓋掉組件本身可能產(chǎn)生的bug(error) => {console.log(error);})}上面使用的是?fetch?的方式請求數(shù)據(jù),?fetch?是前沿的標(biāo)準(zhǔn),它是?Ajax?的替代品,它的?API?是基于?Promise?設(shè)計的,舊版本的瀏覽器不支持?fetch?,需要用?polyfill?es6-promise
具體更詳細的?fetch?使用,可參照?MDN?文檔的
- 方式三:使用?JQ?的?Ajax
jquery?是一個庫,在?React?中你想要用時,得先安裝,使用該方法請求數(shù)據(jù)不是不可以,但是不推薦
然后在你需要請求數(shù)據(jù)的文件處,引入?jquery
import $ from 'jquery';然后在?componentDidMount?生命周期函數(shù)內(nèi),使用?jquer?請求數(shù)據(jù)的方法,下面以?$.get()?為例,?$?至于?$.post()?,?$.ajax()?使用方式可自行查閱的
componentDidMount(){/*$.get('/api/goodlist', function(res){console.log(res);this.setState({list: res.goodLists})}.bind(this)) // 這里必須手動綁定this*/// 等價于下面的,如果不手動綁定,可以使用箭頭函數(shù),避免this的綁定$.get('/api/goodlist', (res) => {console.log(res);const { goodlists } = res;this.setState({list: goodlists})})}上面是使用?jquery?中提供的方法?Ajax?請求數(shù)據(jù),我們只需要請求一數(shù)據(jù),但卻要把整個?jquery?庫都給引入進來,這個按照當(dāng)今的按需加載模塊化開發(fā)的話,是非常不合理的,于是就有了?fetch?,和?axios?的解決方案
在?React?中推薦使用?axios?或者?fetch?的方式進行?Ajax?請求數(shù)據(jù)
- 方式四:使用?request?庫?:?
這個不僅僅是在?Vue?,?React?等框架中使用,在微信小程序里?Ajax?請求數(shù)據(jù)也是支持的
這個?request?模塊也是非常流行和好用的,在這里不提一下,都覺得埋沒了的
使用時,先要安裝?request?模塊然后在安裝?request-promise?模塊,因為?request-pormise?是依賴于?request?,所以兩個依賴都得依次安裝
npm install -S requestnpm install -S request-promise然后在你需要使用請求數(shù)據(jù)的文件上方引入?request-promise?庫,調(diào)用一個?rp?函數(shù)
import rp from 'request-promise';然后在?componentDidMount?內(nèi)進行?Ajax?的數(shù)據(jù)請求,如下代碼所示
componentDidMount(){// 使用request-promise請求數(shù)據(jù)// 注意這里的this.baseUrl不支持/api/goodlist.json方式,下面的this.baseUrl是http://localhost:4000/api/goodlist,以及真實的地止,都是可以的rp(this.baseUrl).then(res => {// 這里要注意的是res返回的是一個字符串,需要用JSON.parse()方法將字符串轉(zhuǎn)化為json對象const { goodlists } = JSON.parse(res);this.setState({list: goodlists})}).catch(error => {console.log(error);})}上面是使用?request-promise?的方式實現(xiàn)?Ajax?數(shù)據(jù)的請求也是可以的,注意使用該方式時,無法使用本地?mock?數(shù)據(jù)的
它也是支持?promise?對象,注意,當(dāng)返回成功的?response?的類型是一個?json?字符串格式,你需要用?JSON.parse()?的方式
將?json?字符串,轉(zhuǎn)化為?json?對象,然后做處理的
如果你是使用?axios?的方式請求數(shù)據(jù),那么是不用進行?json?序列的格式化的
小結(jié)
在?React?中請求數(shù)據(jù)的幾種方式
- axios?(普遍常用)
- fetch?方法(嘗鮮,顯逼格用)
- jquery?Ajax?(不推薦使用)
- request?(常用,僅次于?axios?使用頻率)
注意:都是放在?componentDidMount?函數(shù)中進行數(shù)據(jù)請求的
在本地的?public?目錄下?mock?本地數(shù)據(jù)
這種方式比較簡單,直接在工程?public?目錄下創(chuàng)建一個?api?文件夾,新建一個?json?文件就可以了
若使用?axios?進行數(shù)據(jù)的請求,或者?fetch?的方式,?url?以反斜杠?/?開頭就可以了,如上示例代碼所示,但是若是?request?的方式,?url?寫成反斜線/的方式是不生效的
使用?request?的方式,需要帶上?http?協(xié)議,它也支持線上接口
若是遇到跨域問題,在請求頭?headers?中,添加?Access-Control-Allow-Origin:?*?即可
這個我們在稍后的?mockoon?工具中會介紹到
react-ajax├── package-lock.json├── package.json├── public // 在該目錄下創(chuàng)建一個api文件夾,把需要的模擬的數(shù)據(jù)放在一個json文件即可│ ├── api│ │ └── goodlist.json│ ├── favicon.ico│ ├── index.html│ └── manifest.json├── README.md├── src│ ├── App.js│ ├── index.js│ └── style.css└── yarn-error.log使用?charles?抓取本地化模擬數(shù)據(jù)
charles?是一款代理服務(wù)器,通過將自己設(shè)置成系統(tǒng)的網(wǎng)絡(luò)訪問代理服務(wù)器,然后截取請求和請求結(jié)果達到分析抓包的目的,該軟件是用?java?寫的,安裝?charles?的時候,先要裝好?Java?壞境,也就是?Jdk?壞境的設(shè)置
下面就來看看?charles?的簡單具體使用
先百度百科?charles?下載該工具,下一步,下一步安裝就好,當(dāng)然你在后臺回復(fù)【?charles?下載】也是獲取到的
使用方式如下所示:
注意:?charles?的?port?端口號與?React?本地啟動的服務(wù)端口號一致即可
在你沒有配置?charles?工具代理服務(wù)時,若該假數(shù)據(jù)的文件放置在項目根目錄?public?之外,這時請求?url?,?/api/goodlist?是會報錯的
換而言之,假數(shù)據(jù)放置在?public?目錄下,不使用?charles?等其他代理工具,也能成功,因為在?React?中的?webpack?自動的幫你處理了,會自動的找到?public?目錄下的文件
當(dāng)然除了?charles?還有?mockoon?等其他一些工具的
使用?mockoon?進行?mock?本地數(shù)據(jù)
使用該方式時,需要你去官方下載?mockoon?工具,當(dāng)然你若懶于百度谷歌,你在后臺回復(fù)【mockoon】,這里我只提供了?windows?版本的,?linux?與?Mac?用戶可自行解決
mockoon?配置如下所示
使用?Easy?Mock?偽造數(shù)據(jù)
Easy?Mock?這是大搜車技術(shù)團隊一個開源偽造數(shù)據(jù)的工具,是一個可視化,并且能快速生成模擬數(shù)據(jù)的持久化服務(wù)
easy-mock?結(jié)合了?mock.js?,支持接口代理,?Restful?風(fēng)格等非常好用的功能
把上面代碼中的?baseUrl?換成線上?easy-mock?的就可以了
this.baseUrl ='https://easy-mock.com/mock/5b24e12cf076d94c646a9aa2/api/googlists';至于更多?easy-mock?工具的使用,自己可以多試一試的,有了它,就可以不依賴后端接口了,等后端接口弄好了,直接替換就可以了的
小結(jié)
mock?本地數(shù)據(jù)的幾種方式
- 在本地的?public?目錄下?mock?本地數(shù)據(jù)(最簡單粗暴,常用)
- 使用?charles?抓取本地化模擬數(shù)據(jù)
- 使用?mockoon?進行?mock?本地數(shù)據(jù)
- 使用?easy-mock?偽造接口數(shù)據(jù)(推薦多用)
結(jié)語
本文主要講解了?React?中如何發(fā)送?Ajax?請求,其中發(fā)送請求放置的地方應(yīng)當(dāng)在?componentDidMount?組件掛載完這個生命周期內(nèi),而發(fā)送?Ajax?的方式有?axios?,?fetch?,?Jquery?Ajax?,以及?request?的方式,其中?axios?與?fetch?,?request?是主流的方式
同時介紹了在項目的根目錄?public?文件夾下放置模擬的假數(shù)據(jù),個人覺得這個很簡單粗暴,但是唯一不足是你得自己手動的編寫數(shù)據(jù)
而利用?charles?和?mockoon?工具攔截本地的請求,mock?數(shù)據(jù),需要你額外的配置一下的
當(dāng)然最后介紹了?easy-mock?這個非常好用的模擬后端假數(shù)據(jù)的工具
以上的代理數(shù)據(jù)模擬手段選擇其中一種自己喜歡的就可以了,工具無好壞之分,自己用的爽就可以,不過個人推薦使用?easy-mock?,但是其他方式也不賴,要是不是線上的,斷網(wǎng)了
那么其他方法就比較適用了,之所以介紹了不同的工具,主要是開拓自己的思路
這個工具用得不爽,就用另外一個的,總有一個適合自己的
總結(jié)
以上是生活随笔為你收集整理的React基础-React中发送Ajax请求以及Mock数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黑莓硌手的Passport变圆了
- 下一篇: 紫阳的日常——第一章 拒绝访问的高考成绩