1. 程式人生 > >在 React 應用中獲取資料

在 React 應用中獲取資料

640?wx_fmt=jpeg

可以說 React 是構建 web 應用最流行的庫。然而,它並不是全能的 web 框架。它只關注 MVC 中的 view 模組。

React 整個生態系統可以解決其它問題。這篇教程中,你將會學到如何在 React web 應用中獲取資料並顯示。這很重要。 在整個 React 元件中有幾個地方都可以獲取遠端資料。何時獲取資料是另外一個問題。你還需要考慮用何種技術獲取資料、資料儲存在哪裡。

在教程結束後,你會清楚的知道 React 中該如何獲取資料,不同方法的利弊和如何在 React 應用中使用這些技術。

640?wx_fmt=png

開始

640?wx_fmt=png

讓我們用 create-react-app 建立一個 React 應用的框架:

> create-react-app react-data-fetcher

我們會得到一個精緻的結構目錄。如果,你不熟悉 create-react-app,可以先看看 README 檔案。

640?wx_fmt=png

建立簡單的服務

640?wx_fmt=png

我建立了一個簡單的 quotes 服務。這篇教程的重點不是它,它可以提供遠端 API 用來演示如何在 React 中獲取資料。 為了滿足你們的好奇心,它是一個基於 hug 框架 (http://www.hug.rest/)Python 3 的應用,用 Redis 做持久化儲存。

API 非常簡單。/quotes 是一個簡單介面。通過一個 GET 請求返回所有的 quotes,並且你可以通過 POST 請求新增一條記錄。

完整的程式碼可以在 GitHub (https://github.com/the-gigi/quote-service)檢視。

640?wx_fmt=png

App 預覽

640?wx_fmt=png

這個 React 應用 Demo 可以和 quote 服務通訊、顯示所有的 quote 並可以新增新的記錄。

這是截圖:

640?wx_fmt=png

App 的結構非常簡單。我用 create-react-app 建立了一個基礎框架並在 src 目錄中新增兩個元件:QuoteList 和 AddQuoteForm。以下是詳細的目錄結構(不包含 node_moudules):

640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png

QuoteList 函式元件以無序列表的形式展示所有的 quotes。它需要傳入一組資料字串:

import React from 'react'const QuoteList = ({quotes}) =>
quotes.map
(quote => <li key={quote}>{quote}</li>)
export default QuoteList
640?wx_fmt=png640?wx_fmt=png

Fetch 是基於 promise 的 API,它會返回一個物件。為了得到實際的 JSON 資料,你需要對響應物件執行 json() 方法。

fetchQuotes = () => {
this.setState({...this.state, isFetching: true})
fetch(QUOTE_SERVICE_URL)
.then(response => response.json())
.then(result => this.setState({quotes: result,
isFetching: false}))
.catch(e => console.log(e));}
}
640?wx_fmt=png640?wx_fmt=png

當然 React 都是元件。重點是何時何地才去載入獲取遠端資料呢! 如果你能很好的組織程式碼,你應該會有很多的通用元件和一些特定的元件。React 和 JavaScript 通常非常靈活,你可以在任何地方注入業務邏輯。

因為我希望資料一直是最新的,所以,會以輪詢的方式通過 REST API 獲取遠端資料。 但是,初始化資料也非常重要。React 元件的生命週期方法允許你在特定的時間執行你需要的業務邏輯。 componentDidMount()方法會在元件可訪問的時候執行,此時就可以改變元件的 state。這時候獲取遠端資料是非常合適的。

看起來就像這樣:

componentDidMount() {
this.fetchQuotes()
}

如果,你想縮短頁面的第一次可見的時間,你可以考慮在 componentWillMount() 方法中初始化非同步資料,但是,這有可能會在元件未裝載前完成資料請求。我不推薦這麼操作。

640?wx_fmt=png640?wx_fmt=png

在 componentDidMount() 方法中初始化資料是很合理的,但是,我需要經常更新資料。基於 REST API,只有通過輪詢的方式解決。Quote 伺服器非常簡單,而且始終都會返回所有的 quotes。

大多數可擴充套件服務都會提供方法檢查 HTTP 中的 if-modify-since 和 eTag 判斷資料是否有更新。我們的應用中只是在 componentDidMount() 方法中啟動一個 5s 的定時器更新資料,然後,在 componentWillUnmount() 方法清除定時器

componentDidMount() {
this.fetchQuotes()
this.timer = setInterval(() => this.fetchQuotes(), 5000);
}
componentWillUnmount() {
this.timer = null;
}

輪詢的時間間隔由應用決定。如果,你需要實時更新,並後臺有效能要求,可以考慮用 WebSockets 代替 REST。

640?wx_fmt=png640?wx_fmt=png

有時候載入資料會花費很長時間。在這種下,顯示一個進度條或者一個醒目的動畫讓使用者知道程式正在處理,這對使用者體驗有很大的幫助。 當用戶在初始化資料的時候(比如:點選搜尋按鈕)這很重要。

在演示 app 中,當請求時資料時我簡單的顯示一條提示資訊:“請求資料中...”。在 App 元件的 render() 方法中,通過檢查state.isFetching 的值來決定是否顯示提示資訊。

render() {
const title = 'Quotes for ya!'let now = new Date()
return (
<div className='App'>
<h2 className='App-title'>{title}</h2>
<p>{this.state.isFetching ? 'Fetching quotes...' : ''}</p>
<QuoteList quotes={this.state.quotes} />
<AddQuoteForm quote_service_url={QUOTE_SERVICE_URL}/>
</div>
);
}

fetchQuotes() 方法在初始化開始的時候會把 state.isFetching 的值更新為 true,當有響應返回的時候就切換回 false:

 fetchQuotes = () => {


this.setState({...this.state, isFetching: true})
fetch(QUOTE_SERVICE_URL)
.then(response => response.json())
.then(result => this.setState({quotes: result,
isFetching: false}))
.catch(e => console.log(e));
}
640?wx_fmt=png640?wx_fmt=png

在這裡我對錯誤的處理非常有限只是捕獲錯誤並輸出到控制檯。在你的應用中,你可以執行一些重試邏輯、提示使用者或者顯示一些預設的內容。

640?wx_fmt=png640?wx_fmt=png

Fetch API 是有缺陷的。處理響應的時候必須額外的經過 JSON 處理。它也不會捕獲所有的錯誤。 例如,404 將會做為一個正常的響應返回。你必須主動檢查響應的狀態碼並處理捕獲的網路異常。

因此你必須在兩個地方處理錯誤。但是,你可以使用 axios.js 解決這些問題,在新增額外代價的情況下使用更簡潔的程式碼。使用 axios 的程式碼看起來就像這樣:

fetchQuotes = () => {
this.setState({...this.state, isFetching: true})
axios.get(QUOTE_SERVICE_URL)
.then(response => this.setState({quotes: response.data,

isFetching: false}))
.catch(e => console.log(e);

}

這看起來差別並不大,但是這非常有幫助。使用 axios 新增新的記錄程式碼也非常簡潔。以下是 fetch 的版本:

handleSubmitWithFetch = event => {
let data = new FormData()
data.append('quote', this.state.quote)
fetch(this.props.quote_service_url,
{method: 'POST', body: data})
.then(response => response.json())
.catch(e => console.log(e));
event.preventDefault();

}

這是 axios 的版本:

handleSubmit = event => {
axios.post(this.props.quote_service_url,
{'quote': this.state.quote})
.then(r => console.log(r))
.catch(e => console.log(e));
event.preventDefault();
}
640?wx_fmt=png

在這篇教程中,你學到了如何在 React 元件中非同步載入資料。我們也提到了相關的生命週期方法、輪詢、進度條和錯誤的處理。

我們也瞭解到兩個基於 promise 的庫:fetch API 和 axios.js。現在,你可以構建自己的 React 應用了。

在最近幾年中,React 越來越流行。事實上,市場有很多可以供購買、審查、部署的專案。 如果,你查詢更多的 React 資源,不要遲疑請看這裡

專注分享當下最實用的前端技術。關注前端達人,與達人一起學習進步!

長按關注"前端達人"

640?wx_fmt=gif640?wx_fmt=jpeg

相關推薦

React 應用獲取資料

可以說 React 是構建 web 應用最流行的庫。然而,它並不是全能的 web 框架。它只關注

Java應用資料校驗

翻譯:吳嘉俊 ,叩丁狼高階講師。   [譯者注:這篇文章是開源專案CUBA Platform的作者,在這篇文章中,作者闡述了CUBA平臺中關於資料校驗的設計思想和使用方式,可以作為大家在設計資料校驗方面一個比較好的參考。] 我接觸到的很多專案中,對資料校驗這方面內容都

表單獲取資料及cookie的一些方法

一:從表單中獲取資料 public class Demo01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletE

從hive獲取資料

MySQL中獲取資料 public RestMsg<Object> getZhen( HttpServletRequest request) { RestMsg<Object> rm = new RestMsg<Object>();

js獲取資料型別

ES5中,js中資料型別:number、string、boolean、undefined、null、object js中獲取資料型別常用的四種方式 例項: var a = 123, b = true, c = "123", d = undefined, e = nu

Java基礎-----從Excel獲取資料生成shell指令碼

前言 java讀取Excel的驅動包: 連結:https://pan.baidu.com/s/1ejCR9sS2OUmttFYpQnJkKQ 提取碼:58rm 實現1: 從Excel中讀取表名,由於每個欄位會對應一個表名,故讀取的某列會有若干個連續的表名出現,所以用set集合

從表格獲取資料,並在排序後按順序重新排列表格(Javascript)

數字排序出現問題 升序結果出現了一個大的數字反而在小數字的後面 function mySort(arr){ for(var x=0;x<arr.length-1;x++){ for(var y=x+1;y<arr.l

使用springmvc從頁面獲取資料,然後根據獲得的引數資訊進行修改,如果修改的資料含有不是基本資料型別的引數。比如傳的引數有Date型別的資料時,需要我們進行引數型別轉換。

1.1 需求   在商品修改頁面可以修改商品的生產日期,並且根據業務需求自定義日期格式。 1.2 需求分析   由於日期資料有很多格式,所以springmvc沒辦法把字串轉換成日期型別。所以需要自定義引數繫結。前端控制器接收到請求後,找到註解形式的處理器介面卡,對RequestMapping標記的方法進

SpringBoot學習(三)從yml檔案獲取資料和Thymeleaf 模板引擎

SpringBoot現在基本上都是使用application.yml來配置專案中的一些配置條件,在springboot中還可以通過從yml檔案中將yml中的資料直接讀取出來。 一、從yml檔案中獲取資料 在yml配置下面的資訊 book: au

1.簡單例項:ASP.NET下Echarts通過Ajax從資料庫獲取資料

後臺:Test01.ashx.cs:從資料庫獲取資料,通過HTTP請求(HttpContext)實現和前臺資料傳遞json資料 using System; using System.Collections.Generic; using System.Linq; using

ASP.NET+Echarts+Ajax從資料庫獲取資料

html <div class="panel-body"> <div id="signNum" style="height: 400px; width:

使用localStorage解決瀏覽器重新整理後無法再從vuex獲取資料的問題

假設有這樣一個場景:使用者登入後,用vuex管理使用者的資訊,登入成功後進入主介面,在進入主介面後重新整理瀏覽器,此時vuex中的使用者資訊將無法獲取到。那麼應該如何解決?辦法之一是使用localStorage儲存使用者資訊。在登入成功後儲存使用者資訊,重新整理瀏覽器後從lo

React (7) ajax 獲取資料

1.  為什麼要用中介軟體 Action 發出以後,Reducer 立即算出 State,這叫做同步; Action 發出以後,過一段時間再執行 Reducer,這就是非同步。 中介軟體就是讓 Reducer 在非同步操作結束後自動執行 store/index.js&nbs

Django小專案--待辦清單(四)(從表單獲取資料並存入資料庫)

首先進入主頁(要記得先進入虛擬環境並且通過python  mange.py runserver啟動本地伺服器),我們知道主頁匹配的網址是localhost:8000/todo/home,在瀏覽器上輸入並回車。 在頁面的右上角有一個新增待辦事項的按鈕,輸入內容並點選新

Http Get 從伺服器獲取資料 儲存到本地

package com.http.get; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConn

Python 正則表示式從Windows路徑獲取資料

<pre name="code" class="python">1. Regular Expression ^([a-zA-Z]:|\\\\[a-zA-Z0-9_.$ -]+\\[a-z0-9_.$ -]+)?((?:\\|^)(?:[^\\/:*?"<&

Jmeter-從資料庫獲取資料並作為變數傳輸

再今天重新學習,從資料庫中取資料,並作為變數傳到下一個請求中。 首先第一步要匯入mysql驅動包 一、新增JDBC Connection Configuration 設定連結 Database URL: jdbc:mysql:// 資料庫地址 /庫名 JDBC Driver class:com.my

AE獲取資料某欄位唯一值

{ 9              // 得到IFeatureCursor遊標 10             IFeatureCursor pCursor = pFeatureClass.Search( null , false );11 12              // coClass物件例項生成 13

是用JDBC從資料庫獲取資料並以java物件返回

/** * * @param c * for example Person.class * @param primaryKeys * primaryKeys為主鍵,引數順序和表中保持一致 如果id, name

hive從查詢獲取資料插入到表或動態分割槽

轉自:http://www.crazyant.net/1197.html Hive的insert語句能夠從查詢語句中獲取資料,並同時將資料Load到目標表中。現在假定有一個已有資料的表staged_employees(僱員資訊全量表),所屬國家cnty和所屬州st是該表