React Native填坑之旅–Button篇
React Native填坑之旅–動畫
React Native填坑之旅–HTTP請求篇
如果不能從頭到尾的建立一個RN應用,那麼RN將失色不少。本以爲HTTP請求部分需要使用Native的實現,Android和iOS各回各家,各調各庫了。Google了一下之後居然RN可以使用fetch庫。這個庫是用來代替流傳已久的XHR的。
下面看看如何使用fetch 請求Restful API的。API是dribbble的。這個API需要註冊,所以如果你要運行下面的例子的話,最好註冊一下,或者換一個站點的API試試。
隨着ES6,JavaScript內置的支持了Promise這個填補回調地獄大坑的功能。fetch很好的利用了這一點,它的請求返回結果就是Promise。所以,bye回調。
fetch的使用非常簡單,比現在流行的任何Native庫都好用。
fetch('https://api.dribbble.com/v1/shots', init)
.then((response) => response.json())
.then((responseJson) => {
this.setState({message: `${responseJson[0].id} - ${responseJson[0].title}`});
})
.catch(e => {console.log(`error ${e}`)});
其中的init是一個Object或者說是一個字典,裏面包含了關於請求方式是GET或者POST等的信息。看起來是這樣的:
const init = {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': '需要認證數據',
},
};
請求發出之後,在第一個then
方法裏處理response,返回response.json()
,返回的是一個對象。
在第二個then
方法裏消費從response裏提取出來的json數據。因爲該API返回的是一個數組,所以我們取數組第一個元素,並在Alert
中顯示這個元素的id
和title
。
最後,使用一個catch
方法處理萬一發生的異常。這個錯誤顯示在了console裏。你也可以顯示在界面上,不過你要確保這樣做複合UE的要求。在界面上顯示異常用console.error(msg: string)
,顯示警告使用console.warn(msg: string)
。
更新界面
上面提到的都是如何使用fetch請求的。如果你注意代碼的話就會發現裏面已經包含了如何更新界面的部分。這裏在詳細解釋一下。
在constructor
方法裏設置組件的state
初值爲this.state = {message: ''};
。在fetch成功的獲取到數據,或者出現錯誤的時候(本例的做法是在console裏打印log,這是適合於測試不適合產品環境)更新組件的state
。
this.setState({message: `${responseJson[0].id} - ${responseJson[0].title}`});
那麼組件就會根據state值更新組件:
<Text style={{marginTop: 10}}>{this.state.message ? this.state.message : "Empty"}</Text>
是不是非常簡單。
全部代碼
import React from 'react';
import {
View,
Alert,
Text
} from 'react-native';
import Button from '../view/touchableButton';
export default class HomeController extends React.Component {
constructor(props) {
super(props);
this.state = {
message: ''
};
this.fetchAction = this.fetchAction.bind(this);
}
componentDidMount() {
}
fetchAction() {
this.setState({message: 'Empty'});
const init = {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': '需要認證',
},
// body: JSON.stringify({
//
// })
};
fetch('https://api.dribbble.com/v1/shots', init)
.then((response) => response.json())
.then((responseJson) => {
this.setState({message: `${responseJson[0].id} - ${responseJson[0].title}`});
})
.catch(e => {console.log(`error ${e}`)});
}
render() {
return (
<View style={{flex: 1, marginTop: 100, alignItems: 'center'}}>
<Button style={{marginTop: 50}} buttonTitle='Click to fetch'
onFetch={this.fetchAction} />
<Text style={{marginTop: 10}}>{this.state.message ? this.state.message : "Empty"}</Text>
</View>
);
}
}