1. 程式人生 > >React學習(4)——向伺服器請求資料並顯示

React學習(4)——向伺服器請求資料並顯示

 

 

  本文中涉及到的技術包括:node.js/express伺服器的搭建、fetch傳送資料請求。

    在之前的幾篇文章中,介紹瞭如何搭建基礎的React專案,以及一些簡單知識,現在,我們還需要掌握如何用React來向後臺伺服器發起HTTP請求,來獲取資料。因為一個網站光有靜態的頁面是不夠的,只能稱其為靜態網站,我們需要獲取到資料才能讓網頁呈現更為豐富的內容。

    現在的網站開發一般都採用前後端分離的開發方式。前端人員負責前端頁面的實現,後端人員負責提供資料,前端頁面將通過訪問api介面的方式來連結後臺,獲取相應的資料,如下圖所示:

  目前很流行的方式是通過JQuery中的 AJAX 方法來獲取資料,引入JQuery後使用 $.ajax() 去訪問特定的url地址,通過GET、POST等方式進行資料通訊。本文中採用的方式是通過 Fetch 方法來進行資料通訊,同樣可以向後臺伺服器發起GET、POST等請求。各位也可以直接使用原生的 XMLHttpRequest 方法來實現。

   我們現在有了請求資料的方法,那麼我們請求的物件在哪裡呢,就需要我們親自動手來搭建後臺伺服器了。用於構建後臺伺服器的技術有許多, .NET、JAVA、PHP都是不錯的選擇。本文我們將在 node.js 平臺中使用 express 框架來搭建本地伺服器。為什麼選擇node.js呢,因為我們的React專案是就跑在node.js環境中的,各位在搭建React專案的同時對node.js應該已經有所熟悉,我們也不用特地去學習一門後臺開發語言(當然,如果你已經掌握了其他的後臺開發技術,也可以用自己熟悉的方式來搭建後臺伺服器,只需要向我們的React專案提供api介面)

  下面,我們就來搭建後臺伺服器,大家可以參照如下連結中的教程,其中講得很詳細:

        http://www.runoob.com/nodejs/nodejs-express-framework.html

   現在我們來開始搭建 node.js 伺服器,建立一個專案資料夾,在CMD命令列中輸入:

        cnpm install express --save   (cnpm需要另行安裝,用npm效果一樣,只是慢一點)

    安裝完後我們來檢視一下專案資料夾中的內容

express相關的依賴包已經被放在了 node_modules 資料夾下,package.json用於記錄已安裝的專案依賴包等資訊。

    下面來依次匯入依賴包,搭建專案環境。

    在CMD命令列中依次輸入:

        cnpm install body-parser --save
        cnpm install cookie-parser --save
        cnpm install multer --save

    檢視一下package.json檔案內容,我們可以看到這些依賴包的資訊,json檔案不能直接開啟,大家可以使用各種文字編輯器,這裡本人採用的是VScode,檔案內容如下:

{
"dependencies": {
"body-parser": "^1.18.2",
"cookie-parser": "^1.4.3",
"express": "^4.16.3",
"multer": "^1.3.0"
}
}

  那麼,現在配置好了環境,接下來我們就要開始搭建服務了,建立一個名稱為:myserver.js 的檔案,在其中輸入如下程式碼

var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('This is test message!');
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("應用例項,訪問地址為 http://%s:%s", host, port)
})

  

   其中建立了一個對於GET請求的監聽介面,地址為“/”,由於我們是在本地搭建伺服器,所以這個介面的完整地址就是 localhost:8081/  ,其中的8081就是伺服器在本地環境中的訪問埠號。在res.send()函式中我們放入了一條字串資訊,內容為 'This is test message!' ,也就是api介面返回的資訊。

    儲存這個檔案並放在專案主目錄下,在CMD命令列中輸入如下指令:

        node myserver.js

    然後我們就成功啟動了伺服器,埠號為8081,我們可以直接在瀏覽器中輸入 localhost:8081/ 來訪問,內容如下:

    我們可以在瀏覽器中看到之前儲存在 myserver.js 檔案中的字串。現在我們已經能夠從瀏覽器中看到api介面給出的資料,然後,可以試著在React專案中訪問api介面。

    用VScode編輯器開啟已經建立完成的React專案目錄 

    我們建立一個元件,內容如下:

import React from 'react';

class Page2 extends React.Component{
constructor(props){ //建構函式
super(props);
this.state = {
mytext : '',
}
}

getData(){ //請求資料函式
fetch(`http://127.0.0.1:8081/`,{
method: 'GET'
}).then(res => res.text()).then(
data => {
this.setState({mytext:data})
}
)
}

componentWillMount(){
this.getData();
}

    render(){
    return(<div><div>{this.state.mytext}</div></div>);
  }
}

export default Page2;

  

下面來分析一下程式碼,首先,在上方的“建構函式”constructor中,設定了State的初值,新增一個mytext屬性,初始值為空,其他內容是標準的構造語法,可以參照React官方資料。之後,我們建立一個getData() 函式,用於實現fetch方法獲取後臺伺服器的資料。

    如上所示,fetch方法有兩個傳入的引數,一個是url,也就是後臺api介面所在的地址,另一個是{method:'GET'},意思是採用GET方式與後臺伺服器進行通訊。後面的 .then( ) 方法將上面傳回來的結果進行進一步的處理,將結果作為 res這個物件傳入,並使用 .text() 方法使其轉化為字串型別,然後再下一個 .then( ) 方法中將上一步的返回值作為data 賦值給 state裡的mytext。

    (Fetch的詳細用法各位可以參照一下網上的資料,本文只是簡單使用,不做太多介紹)

    現在我們有了獲取資料的函式,需要呼叫這個函式,這裡要注意的是,我們不能直接在下方的render函式裡呼叫getData( ),那樣會造成頁面死迴圈,由於React的特性,在render函式中,每當State被改變時就會重新渲染元件,getData( )函式中涉及到了對State的更改,所以React系統會重新去渲染頁面==>載入render函式==>重新呼叫getData( )==>重新渲染頁面==>一直死迴圈...

    所以我們需要使用到React的生命週期函式,componentWillMount( ),將getData函式放置在其中,這個生命週期函式會在元件被渲染前呼叫,這個時候改變State就不會造成死迴圈。

    (關於生命週期各位可以參照React官方文件   https://doc.react-china.org/ )

然後,我們需要將State中的資料顯示出來,在render函式return的標籤中如上所示將 this.state.mytext 的內容顯示出來。

    儲存檔案,用 npm start 啟動專案,輸入 localhost:3000 頁面將會呈現如下內容:

    注意,這裡會出現一個問題,無法實現跨域請求,也就是說,我們的React專案所在的 3000 埠與後臺服務應用的 8081 埠不能進行通訊,這是出於安全考慮,為了解決這一問題,可以在後臺服務應用 myserver.js 中加入下面這段程式碼:把rapp.get那替換掉就可以了 之後重啟一下 node myserver.js

app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",' 3.2.1');
res.header("Content-Type", "application/json;charset=utf-8");
res.send("this is templace!!!")
next();
});

  

   這樣就可以讓React專案進行跨域請求,顯示資料。

   現在,我們成功地從後臺api中獲取並顯示字串資訊,那麼其他型別的資料也可以這樣嗎?

    下面我們來實現對json格式資料的獲取。

    首先要對 node.js/express 服務應用進行改造,程式碼如下:

var express = require('express');
var app = express();
app.all('/json', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By",' 3.2.1');
    res.header("Content-Type", "application/json;charset=utf-8");
    
    let myjson = {
        name : '盒裝牛奶',
        price : '3元',
        date : '2018年1月1日'
        }
        res.send(myjson);
    next();
    });
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("應用例項,訪問地址為 http://%s:%s", host, port)
})

  

    在程式碼中,我們添加了一個get方法,地址為'/json',也就是 localhost:8081/json ,在方法中建立了一個json格式的資料物件 myjson,然後將其傳回。

    ctrl+c 退出原來的服務,使用 node myserver.js 重新啟動服務後,我們用瀏覽器來訪問 localhost:8081/json ,內容如下:

 

 

    我們成功地從後臺伺服器中獲取了json格式的資料,下面我們要在react專案中將其顯示出來,改造Page2元件,程式碼如下:

import React from 'react';

class Page2 extends React.Component{
constructor(props){ //建構函式
super(props);
this.state = {
mytext : '',
}
}

getData(){ //請求資料函式
fetch(`http://127.0.0.1:8081/json`,{
method: 'GET'
}).then(res => res.json()).then(
data => {
this.setState({mytext:data})
}
)
}

componentWillMount(){
this.getData();
}


render(){

return(
<div>
<div>{this.state.mytext.name}</div>
<div>{this.state.mytext.price}</div>
<div>{this.state.mytext.date}</div>
</div>
);
}
}
export default Page2;

  

    其中,fetch函式的url要改變為 localhost:8081/json ,在後面的.text( ) 方法要改為 .json( ),將資料轉換為json格式,在render函式的return裡面建立3對<div>標籤,分別顯示mytext資料物件的name、price、date屬性,在頁面中我們可以看到:

上所示,我們儲存在後臺伺服器中的json資料被傳遞了過來,並由React應用渲染在了頁面上。

    到此,本篇文章的內容就結束了,此次介紹瞭如何搭建 node.js/express 伺服器,以及介紹瞭如何在React專案中使用Fetch獲取資料,存放在State中,並渲染出來。希望對各位有所幫助,也是對本人學習心得的記錄,感謝各位支援。後續還會有React相關文章更新。

 

 記錄學習。看一遍不如自己實踐一次,勤動手,勤動腦,邁出第一步!

看後續文章的 可以點選這個連結,https://blog.csdn.net/daxiazouyizou/article/details/80196815