前言
去年我寫了一個(gè)教程晨继,手把手教你寫一個(gè)RN小程序!,里面其實(shí)對(duì)ListView已經(jīng)做了一些詳解,不過由于那個(gè)項(xiàng)目接口停止維護(hù),再加上RN教程準(zhǔn)備寫一個(gè)系列砚嘴,所以重新寫一篇文章來完善ListView的使用。另外拘鞋,ListView一般都是配合數(shù)據(jù)來使用的落剪,所以這里我把網(wǎng)絡(luò)請(qǐng)求也順帶簡(jiǎn)單的講解一下。本文會(huì)使用豆瓣api來進(jìn)行數(shù)據(jù)的解析主卫。
fetch()
React Native提供了和web標(biāo)準(zhǔn)一致的Fetch API工育,用于滿足開發(fā)者訪問網(wǎng)絡(luò)的需求虾宇。那么如何使用呢?
fetch使用
fetch('https://api.douban.com/v2/movie/top250')//豆瓣電影Top250
從任意地址獲取數(shù)據(jù)如绸,只需要這么寫就可以了嘱朽,把地址傳遞給fetch()方法。
fetch('https://api.douban.com/v2/movie/top250')
//ES6的寫法左邊代表輸入的參數(shù)右邊是邏輯處理和返回結(jié)果
.then((response) => response.json())
.then((responseData) => {
this.setState({
data: responseData,
});
})
.done();
以上是fetch通過get請(qǐng)求獲取的數(shù)據(jù)怔接,這個(gè)可以獲取數(shù)據(jù)源data搪泳,那么我們登錄注冊(cè)一般都是用的post提交方式,那該如何寫呢扼脐?
fetch()還有可選的第二個(gè)參數(shù)用來指定請(qǐng)求的方法岸军,你可以指定header參數(shù),或是指定使用POST方法瓦侮,又或是提交數(shù)據(jù)等等艰赞。
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',//指定POST方法
headers: {//指定header參數(shù)
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({//設(shè)置提交的數(shù)據(jù)
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})
.then((response) => response.json())
.then((responseData) => {
//responseData是服務(wù)器返回的data
}
})
.done();
簡(jiǎn)單的fetch()請(qǐng)求就介紹到這里,有想法的同學(xué)可以參考該文章:【翻譯】這個(gè)API很“迷人”——(新的Fetch API)
溫馨提示肚吏,iOS默認(rèn)不支持http請(qǐng)求方妖,請(qǐng)?jiān)赬code中設(shè)置
1、在Info.plist中添加NSAppTransportSecurity類型Dictionary须喂。
2吁断、在NSAppTransportSecurity下添加NSAllowsArbitraryLoads類型Boolean,值設(shè)為YES
組件生命周期
一般來說,一個(gè)組件類由 extends Component創(chuàng)建坞生,并且提供一個(gè) render方法以及其他可選的生命周期函數(shù)仔役、組件相關(guān)的事件或方法來定義。
getInitialState()函數(shù) 初始化 this.state 的值是己,只在組件裝載之前調(diào)用一次又兵。
getDefaultProps()函數(shù) 只在組件創(chuàng)建時(shí)調(diào)用一次并緩存返回的對(duì)象,因?yàn)檫@個(gè)方法在實(shí)例初始化之前調(diào)用,所以在這個(gè)方法里面不能依賴 this 獲取到這個(gè)組件的實(shí)例卒废。
render() 組裝生成這個(gè)組件的 HTML 結(jié)構(gòu) ,必須要有的函數(shù)
生命周期函數(shù)
componentWillMount() 只會(huì)在裝載之前調(diào)用一次沛厨,在 render 之前調(diào)用,你可以在這個(gè)方法里面調(diào)用 setState 改變狀態(tài)
componentDidMount() 只會(huì)在裝載完成之后調(diào)用一次摔认,在 render 之后調(diào)用逆皮,從這里開始可以通過 ReactDOM.findDOMNode(this) 獲取到組件的 DOM 節(jié)點(diǎn)。
componentWillUnmount() 卸載組件觸發(fā)
更新組件時(shí)觸發(fā)的函數(shù):
componentWillReceiveProps()
shouldComponentUpdate()
componentWillUpdate()
componentDidUpdate
ListView
ListView是一個(gè)常用核心組件参袱,用于高效地顯示一個(gè)可以垂直滾動(dòng)的變化的數(shù)據(jù)列表电谣。通過創(chuàng)建一個(gè)ListView.DataSource數(shù)據(jù)源秽梅,然后給它傳遞一個(gè)普通的數(shù)據(jù)數(shù)組,再使用數(shù)據(jù)源來實(shí)例化一個(gè)ListView組件剿牺,并且定義它的renderRow回調(diào)函數(shù)企垦,這個(gè)函數(shù)會(huì)接受數(shù)組中的每個(gè)數(shù)據(jù)作為參數(shù),返回一個(gè)可渲染的組件(作為listview的每一行)晒来。
cellRow(data) {
return (
<View >//這個(gè)是cell的視圖
</View>
);
}
render() {
return (
<View style={styles.container}>
<ListView
initiaListSize={1} //指定在組件剛掛載的時(shí)候渲染多少行數(shù)據(jù)钞诡。用來確保首屏顯示合適數(shù)量的數(shù)據(jù)
//onChangeVisibleRows={()=>{}}//當(dāng)可見的行的集合變化的時(shí)候調(diào)用此回調(diào)函數(shù)
//onEndReached={()=>{}}//當(dāng)所有的數(shù)據(jù)都已經(jīng)渲染過,并且列表被滾動(dòng)到距離最底部不足onEndReachedThreshold個(gè)像素的距離時(shí)調(diào)用湃崩。配合onEndReachedThreshold使用
onEndReachedThreshold={10} //調(diào)用onEndReached之前的臨界值荧降,單位是像素。
pageSize={3} //每次渲染的行數(shù)
removeClippedSubviews={true}//用于提升大列表的滾動(dòng)性能攒读。需要給行容器添加樣式overflow:'hidden'誊抛。(Android已默認(rèn)添加此樣式)。此屬性默認(rèn)開啟整陌。
dataSource={this.state.dataSource} //列表依賴的數(shù)據(jù)源
renderRow={this.cellRow.bind(this)}//(rowData, sectionID, rowID, highlightRow) => renderable 從數(shù)據(jù)源(Data source)中接受一條數(shù)據(jù),以及它和它所在section的ID瞎领。返回一個(gè)可渲染的組件來為這行數(shù)據(jù)進(jìn)行渲染泌辫。
style={styles.listView}
/>
</View>
);
}
renderSectionHeader()方法會(huì)為每個(gè)section提供一個(gè)粘性的標(biāo)題
scrollTo(...args),滾動(dòng)到指定的x,y偏移處。
ListView和Fetch()結(jié)合使用
1.新建一個(gè)文件
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
ListView
} from 'react-native';
export default class TestDemo extends Component {
render() {
return (
<View style={styles.container}>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex:1,
}
});
2.引入ListView
<ListView initiaListSize={2}
pageSize={2}
dataSource={this.state.dataSource}
renderRow={this.cellRow.bind(this)}
style={styles.listView}
/>
然后根據(jù)文檔添加數(shù)據(jù)源dataSource
constructor(props){
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {dataSource: ds.cloneWithRows([{},])};
}
我們的Cell也必定不能少啊
cellRow(data) {
return (
<TouchableOpacity onPress={()=>this.rowPressed(data)}>
<View>
<View style={styles.cellStyle}>
<Image style={{margin:10,width:100, resizeMode:'contain',height:(WIDTH-40)/2}}
source={{uri: data.images.large}}
/>
<Text style={styles.title}>{data.title}</Text>
</View>
</View>
</TouchableOpacity>
);
}
OK基本上完工九默,說好的fetch呢震放?別著急,慢慢來
componentDidMount() {
this.fetchData();
}
fetchData() {
fetch(GET_URL)
//ES6的寫法左邊代表輸入的參數(shù)右邊是邏輯處理和返回結(jié)果
.then((response) => response.json())
.then((responseData) => {
if (responseData.subjects) {
//我們需要在數(shù)據(jù)解析完成的時(shí)候來setdataSource
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.subjects),
});
} else {
//do Something
Alert.alert('暫時(shí)沒有數(shù)據(jù)');
}
})
.done
}
恩驼修,測(cè)試的話殿遂,GET_URL是https://api.douban.com/v2/movie/top250,
至此基本上已經(jīng)完工,大家可以試著做一下
)
最后
當(dāng)然要附上我們的源碼了乙各,在我的github上:React-Native-Study
后續(xù)會(huì)更新帶Header的ListView和用ListView寫的九宮格墨礁,喜歡的同學(xué)可以支持一下,么么噠耳峦!