繼續上一篇React Native第一個Demo(1) 1、網路擷取真實資料 1.1定義變數
把下面url變數放在index.ios.js頂部,通常是要放在 imports下面。
var REQUEST_URL = 'https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json';
1.2初始化
添加一些初始化,this.state.movies === null,這樣我們可以判斷movies資料是否被載入了。
constructor(props) { super(props); this.state = { movies: null, }; }
1.3 fetchData()
在組件載入時,擷取資料。資料返回時,回調設定state的movies為電影資訊資料列表。
componentDidMount() { this.fetchData(); }fetchData() { fetch(REQUEST_URL) .then((response) => response.json()) .then((responseData) => { this.setState({ movies: responseData.movies, }); }) .done(); }
1.4 loading的視圖和渲染擷取的資料
擷取資料返回後,設定state,render被再次調用,這時this.state.movies不為null,調用renderMovie設定和展示資料到介面上。
render() { if (!this.state.movies) { return this.renderLoadingView(); } var movie = this.state.movies[0]; return this.renderMovie(movie); } renderLoadingView() { return ( <View style={styles.container}> <Text> Loading movies... </Text> </View> ); } renderMovie(movie) { return ( <View style={styles.container}> <Image source={{uri: movie.posters.thumbnail}} style={styles.thumbnail} /> <View style={styles.rightContainer}> <Text style={styles.title}>{movie.title}</Text> <Text style={styles.year}>{movie.year}</Text> </View> </View> ); }
2、ListView展示網路資料
為什麼要用ListView不用scrollview或把資料直接顯示出來呢。 因為ListView只渲染展示部分的資料,效率高效能好。 2.1 增加ListView模組
import React, { Component,} from 'react';import { AppRegistry, Image, ListView, StyleSheet, Text, View,} from 'react-native';
2.2 修改構造器和render
增加dataSource變數和loaded,方便使用,避免this.state.movies兩次儲存。rowHasChanged是 react組件紀錄 state 是否更新的一個方法, 如果是等於,state變化 頁面不更新 , 不等於,如果state變化 頁面立即更新。
constructor(props) { super(props); this.state = { dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }), loaded: false, }; } render() { if (!this.state.loaded) { return this.renderLoadingView(); } return ( <ListView dataSource={this.state.dataSource} renderRow={this.renderMovie} style={styles.listView} /> ); }
2.3 fetchData&增加listview的rowstyle
fetchData() { fetch(REQUEST_URL) .then((response) => response.json()) .then((responseData) => { this.setState({ dataSource: this.state.dataSource.cloneWithRows(responseData.movies), loaded: true, }); }) .done(); }//下面增加到stlyes裡 listView: { paddingTop: 20, backgroundColor: '#F5FCFF', },
2.4 完整代碼
import React, { Component,} from 'react';import { AppRegistry, Image, StyleSheet, Text, View, ListView, } from 'react-native'; var REQUEST_URL = 'https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json'; class DemoProject extends Component { constructor(props) { super(props); this.state = { dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }), loaded: false, }; } componentDidMount(){ this.fetchData(); } fetchData() { fetch(REQUEST_URL) .then((response) => response.json()) .then((responseData) => { this.setState({ dataSource: this.state.dataSource.cloneWithRows(responseData.movies), loaded: true, }); }) .done(); } render() { if (!this.state.loaded) { return this.renderLoadingView(); } return ( <ListView dataSource={this.state.dataSource} renderRow={this.renderMovie} style={styles.listView} /> ); } renderLoadingView() { return (<View style={styles.container} > <Text>Loading movies......</Text> </View> ); } renderMovie(movie) { return ( <View style={styles.container}> <Image source={{uri: movie.posters.thumbnail}} style={styles.thumbnail} /> <View style={styles.rightContainer}> <Text style={styles.title}>{movie.title}</Text> <Text style={styles.year}>{movie.year}</Text> </View> </View> ); } }; var styles = StyleSheet.create({ container: { flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, rightContainer: { flex: 1, }, title: { fontSize: 20, marginBottom: 8, textAlign: 'center', }, year: { textAlign: 'center', }, thumbnail: { width: 53, height: 81, }, listView: { paddingTop: 20, backgroundColor: '#F5FCFF', }, }); AppRegistry.registerComponent('DemoProject', () => DemoProject);
參考:http://facebook.github.io/react-native/docs/tutorial.html