Hello World
react native 官方Hello world示例
import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';
class HelloWorldApp extends Component {
render() {
return (
<Text>Hello world!</Text>
);
}
}
// 注意,這里用引號括起來的'HelloWorldApp'必須和你init創(chuàng)建的項(xiàng)目名一致
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);
我們從import開始來看這個程序:
第一行和第二行都是import xxx from 'xxxxx',這句話的意思大概就是從'xxxxx'文件中引入xxx ,import 語句是es6的內(nèi)容,關(guān)于es6的新特性可以看阮一峰老師的書,后邊的文件是一個js文件他只寫了文件名沒有跟上.js后綴,import和from 之間的內(nèi)容就是文件中定義的組件。
接下來看 下面class xxx extends Component{}這個看著有點(diǎn)像JAVA的類繼承語句,這也是es6的內(nèi)容Component是一切界面組件的根類實(shí)現(xiàn)界面組件必須要像上面一樣繼承此類,再看類內(nèi)的代碼render(){returun()}render的中文意思是渲染這就是組件的渲染函數(shù)return括號中的內(nèi)容就是界面上渲染的內(nèi)容
最后一句是AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);我們可以看到registerComponent函數(shù)有兩個參數(shù)第一個參數(shù)是一個字符串是項(xiàng)目的名字,第二參數(shù)是一個表達(dá)式=>符號也是es6的,內(nèi)容符號前面是參數(shù)列表符號后面是方法體,此語句的意思是以HelloWorldApp組件為根組件渲染這個項(xiàng)目,第二個參數(shù)可以替換為你自己想要的方法體,比如:AppRegistry.registerComponent('HelloWorldApp', () => MyApp);MyApp 是繼承自Component的組件。
Props(屬性)
第一個官方示例
大多數(shù)組件可以在創(chuàng)建的時候可以使用各種參數(shù)進(jìn)行定制,這些參數(shù)稱為屬性Props。下面看一個官方示例
import React, { Component } from 'react';
import { AppRegistry, Image } from 'react-native';
class Bananas extends Component {
render() {
let pic = {
uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
};
return (
<Image source={pic} style={{width: 193, height: 110}} />
);
}
}
AppRegistry.registerComponent('Bananas', () => Bananas);
這是一段顯示一張圖片的代碼 其中的Image組件帶了兩個屬性分別為source 和style,source屬性用于指定圖片資源let是es6中新增加的關(guān)鍵字用于指定一個局部變量(詳細(xì)內(nèi)容看書),可以注意到source后面pic被一個{}包圍,這是在jsx代碼中插入js代碼的方式{}中可以寫js代碼。
獲取圖片的兩種方法
1、通過uri加載如上代碼所示:
let pic = { uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg' };
2、通過require
let pic = {require('./icon.png')}
require中的字符串是相對地址或者絕對地址,require()中的參數(shù)必須是一個字面量而不能是一個變量活常量
let path = './icon.png'
let pic = {require(path)} //這會報(bào)錯說找不到相應(yīng)的model
let pic = {require('./icon.png')}//正確
第二個示例
除了組件自帶的屬性我們也可以添加我們自己的屬性,示例如下:
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';
class Greeting extends Component {
render() {
return (
<Text>Hello {this.props.name}!</Text>
);
}
}
class LotsOfGreetings extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Greeting name='Rexxar' />
<Greeting name='Jaina' />
<Greeting name='Valeera' />
</View>
);
}
}
AppRegistry.registerComponent('LotsOfGreetings', () => LotsOfGreetings);
上面的代碼自定義了一個Greeting組件,使用了{this.props.name}去初始化組件,Text的組件中本來不包含這個屬性,是我們自己加的,我們無需任何聲明,只要在使用組件時加入這一個屬性即可。
狀態(tài)(state)
props和state共同控制了一個組件,props在父組件中指定,在指定組件的生命周期中不在改變。對于需要改變的數(shù)據(jù)我們使用state
一般來說,需要在constructor中初始化state,下面是一個實(shí)現(xiàn)文字閃爍效果的例子:
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';
class Blink extends Component {
constructor(props) {
super(props);
this.state = { showText: true };
// 每1000毫秒對showText狀態(tài)做一次取反操作
setInterval(() => {
this.setState({ showText: !this.state.showText });
}, 1000);
}
render() {
// 根據(jù)當(dāng)前showText的值決定是否顯示text內(nèi)容
let display = this.state.showText ? this.props.text : ' ';
return (
<Text>{display}</Text>
);
}
}
class BlinkApp extends Component {
render() {
return (
<View>
<Blink text='I love to blink' />
<Blink text='Yes blinking is so great' />
<Blink text='Why did they ever take this out of HTML' />
<Blink text='Look at me look at me look at me' />
</View>
);
}
}
AppRegistry.registerComponent('BlinkApp', () => BlinkApp);
樣式
在react native中,我們使用js來寫樣式。所有的核心組件都接受style屬性,這些樣式和css一樣唯一的區(qū)別就是,按照js的語法改用了駝峰寫法,background-color->backgroundColor
最簡單的寫法如下:
<Text style={{backgroundColor:'red',height:50,width:50}} >red<Text>
實(shí)際開發(fā)推薦用法:在StyleSheet.create中幾種定義樣式,如下
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigblue}>just bigblue</Text>
<Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
<Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
</View>
);
}
}
const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
AppRegistry.registerComponent('LotsOfStyles', () => LotsOfStyles);
寬度和高度
指定寬高
最簡單的方式:直接指定height和width,在react native中像素都是luo'ji邏輯像素?zé)o單位,例子如下:
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
class FixedDimensionsBasics extends Component {
render() {
return (
<View>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
<View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
</View>
);
}
};
// 注冊應(yīng)用(registerComponent)后才能正確渲染
// 注意:只把應(yīng)用作為一個整體注冊一次,而不是每個組件/模塊都注冊
AppRegistry.registerComponent('AwesomeProject', () => FixedDimensionsBasics);
彈性(Flex)寬高
在style中使用flex可以動態(tài)的擴(kuò)張和收縮。在一個父組件只有一個子組件的情況下給子組件指定flex:1可以使得子組件撐滿父組件,但子組件有多個時子組件按照各自的權(quán)重分配空間
組件能夠撐滿剩余空間的前提是父容器的大小不為0,父容器沒有指定width和height,也沒有指定flex,那么父容器的尺寸就為0。
下面是一個flex使用示例:
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
class FlexDimensionsBasics extends Component {
render() {
return (
// 試試去掉父View中的`flex: 1`。
// 則父View不再具有尺寸,因此子組件也無法再撐開。
// 然后再用`height: 300`來代替父View的`flex: 1`試試看?
<View style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}} />
<View style={{flex: 2, backgroundColor: 'skyblue'}} />
<View style={{flex: 3, backgroundColor: 'steelblue'}} />
</View>
);
}
};
AppRegistry.registerComponent('AwesomeProject', () => FlexDimensionsBasics);
效果如下:

FlexBox布局
一般來說我們使用flexDirection、alignItems、justifyContent來實(shí)現(xiàn)大多數(shù)的布局
RN的flexbox布局和web中的css布局基本類似,只存在少許的差異。首先默認(rèn)值不同:
flexDirection的默認(rèn)值是cloumn而不是row,alignItem默認(rèn)值是stretch而不是flex-start,flex只能指定一個值
FlexDirection
style中指定flexDirection可以指定主軸,他有兩個取值,默認(rèn)值column以及另一個值row,下面是一個例子:
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
class FlexDirectionBasics extends Component {
render() {
return (
// 嘗試把`flexDirection`改為`column`看看
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
</View>
);
}
};
AppRegistry.registerComponent('AwesomeProject', () => FlexDirectionBasics);
效果主軸為水平:


JustifyContent
在style中指定justifyContent可以指定子元素沿著主軸的排列方式,選項(xiàng)有flex-start,center,flex-end,space-around,space-between。
代碼示例:
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
class JustifyContentBasics extends Component {
render() {
return (
// 嘗試把`justifyContent`改為`center`看看
// 嘗試把`flexDirection`改為`cloumn`看看
<View style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
}}>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
</View>
);
}
};
AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
效果圖:
flex-start:

center:

flex-end:

space-around:

space-between:

alignItems
在組件style中指定alignItems可以決定子元素沿著次軸的排列方式。他有四個選項(xiàng):?flex-start、center、flex-end、stretch。
想要stretch生效的話子元素在次軸上不能有固定的尺寸
示例代碼:
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
class AlignItemsBasics extends Component {
render() {
return (
// 嘗試把`alignItems`改為`flex-start`看看
// 嘗試把`justifyContent`改為`flex-end`看看
// 嘗試把`flexDirection`改為`row`看看
<View style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
}}>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
</View>
);
}
};
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
效果圖:
flex-start:

center:

flex-end:

stretch:此時我們是將主軸設(shè)為row所以垂直方向不能設(shè)置也就是不能設(shè)置高度。

文本輸入
TextInput是一個文本輸入的基礎(chǔ)組件。有一個名為onChangeeText屬性,通過這個屬性可以獲取組件中的文本,下面是代碼例子:
import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, View } from 'react-native';
class PizzaTranslator extends Component {
constructor(props) {
super(props);
this.state = {text: ''};
}
render() {
return (
<View style={{padding: 10}}>
<TextInput
style={{height: 40}}
placeholder="Type here to translate!"
onChangeText={(text) => this.setState({text})}
/>
<Text style={{padding: 10, fontSize: 42}}>
{this.state.text.split(' ').map((word) => word && '??').join(' ')}
</Text>
</View>
);
}
}
// 注冊應(yīng)用(registerComponent)后才能正確渲染
// 注意:只把應(yīng)用作為一個整體注冊一次,而不是每個組件/模塊都注冊
AppRegistry.registerComponent('PizzaTranslator', () => PizzaTranslator);
ScroView的使用
ScrollView是一個通用的容器,可以在其中放入scrollView,下面是一個ScrollView
import React, { Component } from 'react';
import{ AppRegistry, ScrollView, Image, Text, View } from 'react-native'
class IScrolledDownAndWhatHappenedNextShockedMe extends Component {
render() {
return(
<ScrollView>
<Text style={{fontSize:96}}>Scroll me plz</Text>
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Text style={{fontSize:96}}>If you like</Text>
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Text style={{fontSize:96}}>Scrolling down</Text>
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Text style={{fontSize:96}}>What's the best</Text>
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Text style={{fontSize:96}}>Framework around?</Text>
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Text style={{fontSize:80}}>React Native</Text>
</ScrollView>
);
}
}
// 注冊應(yīng)用(registerComponent)后才能正確渲染
// 注意:只把應(yīng)用作為一個整體注冊一次,而不是每個組件/模塊都注冊
AppRegistry.registerComponent(
'IScrolledDownAndWhatHappenedNextShockedMe',
() => IScrolledDownAndWhatHappenedNextShockedMe);
ScrollView是用來顯示數(shù)量不多的元素,它不同于ListView,它會渲染所有的子組件,而不是像ListView一樣只渲染可見的部分
效果圖如下:

這里講一下ScrollView的兩個屬性,第一個
horizontal,這是一個bool類型的屬性,當(dāng)它為true時候他就是一個左右滑動的ScrollView,默認(rèn)值為false垂直滑動 ,另一個屬性是automaticallyAdjustContentInsets這個屬性當(dāng)ScrollView作為TabBar或者Navigator后面的時候,ios是否自動調(diào)整內(nèi)容的范圍(如果ScrollView或者ListView出現(xiàn)莫名其妙的空白那就將這個屬性設(shè)置為false),還有一個要點(diǎn)就是ScrollView一定要指定高度(垂直的時候)或?qū)挾龋ㄋ降臅r候)
ListView
ListView組件用于顯示垂直滾動列表,它只會渲染其中的可見部分適用于長列表,ListView列表必須有兩個屬性,dataSource和renderRow。dataSource是列表的數(shù)據(jù)源,它是一個ListView.DataSource類型對象,redenderRow從dataSource中取數(shù)據(jù)并渲染。
rowhasChange是ListView的dataSource中的必備屬性
下面是一個示例:
import React, { Component } from 'react';
import { AppRegistry, ListView, Text, View } from 'react-native';
class ListViewBasics extends Component {
// 初始化模擬數(shù)據(jù)
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([
'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
])
};
}
render() {
return (
<View style={{paddingTop: 22}}>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData}</Text>}
/>
</View>
);
}
}
// 注冊應(yīng)用(registerComponent)后才能正確渲染
// 注意:只把應(yīng)用作為一個整體注冊一次,而不是每個組件/模塊都注冊
AppRegistry.registerComponent('ListViewBasics', () => ListViewBasics);
例子示例如下:

網(wǎng)絡(luò)
Fetch
React Native提供了和web標(biāo)準(zhǔn)一致的Fetch API
發(fā)起網(wǎng)絡(luò)請求
從任意地址獲取數(shù)據(jù)內(nèi)容,只需要簡單件網(wǎng)址傳給fetch方法即可
fetch('https://www.baidu.com')
fetch有許多可以定制的參數(shù),示例如下:
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})
這段代碼定制了提交方式 請求頭和請求體
處理服務(wù)器的響應(yīng)數(shù)據(jù)
代碼示例:
fetch('http://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
fetch語句返回的是一個Promise對象,可以通過then進(jìn)行異步操作promise.then().then(),then中跟的參數(shù)是前面的的返回值。
Navigator
導(dǎo)航器的使用示例:
<Navigator
initialRoute={{ name: 'first', component: LatestRelease }}
configureScene={
(route) => {
return Navigator.SceneConfigs.VerticalUpSwipeJump;
}
}
renderScene={
(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}
}
>
</Navigator>
export default class LatestRelease extends Component {
_showDetail() {
const {navigator} = this.props;
if (navigator) {
navigator.push({
name: 'Detail',
component: Detail,
})
}
}
render() {
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
return (
<View style={{flex: 1}}>
<View alignItems='center'>
<View style={{backgroundColor: '#F8F8FF'}}><Text>最新發(fā)布</Text></View>
<TextInput style={{height: 30, margin: 5, padding: 2, borderColor: 'gray', borderWidth: 1}}
placeholder='搜索'/>
</View>
<View style={{
height: 30,
margin: 5,
backgroundColor: 'deepskyblue',
alignItems: 'center',
flexDirection: 'row'
}}>
<View style={{flex: 1}}>
<Text style={{color: 'white', paddingLeft: 5}}>指標(biāo)</Text>
</View>
<View style={{flex: 1, flexDirection: 'row', justifyContent: 'flex-end'}}>
<Text style={{color: 'white'}}>同比(%) </Text>
</View>
</View>
<ListView
automaticallyAdjustContentInsets={false}
style={{flex: 7, marginLeft: 5, marginRight: 5}}
dataSource={ds.cloneWithRows(['國內(nèi)生產(chǎn)總值', '水泥', '固定資產(chǎn)投資(不含農(nóng)戶)', '民間固定資產(chǎn)投資', '房地產(chǎn)開發(fā)投資', '社會消費(fèi)品零售總額']) }
renderRow={(rowData) =>
<TouchableHighlight onPress={this._showDetail.bind(this) } style={{
height: 40,
marginBottom: 5,
borderBottomWidth: 1,
borderBottomColor: 'lightgray'
}} flexDirection='row' alignItems='center'>
<View style={{flex: 1}} flexDirection='row' alignItems='center'>
<View style={{flex: 9}}>
<Text style={{paddingTop: 5, fontSize: 15}}>{rowData}</Text>
<Text style={{}}>2016Q1-2</Text>
</View>
<View style={{flex: 1}}>
<Text style={{fontSize: 18, color: 'red'}}>+6.7</Text>
</View>
</View>
</TouchableHighlight>}
>
</ListView>
<Button style={{backgroundColor: 'red'}} textStyle={{fontSize: 18}}
children={require('./Icon/add_zb_icon1.png')}
>
Hello!word
</Button>
<ButtonComponent
text="添加指標(biāo)"
textStyle={{letterSpacing: 0,
fontSize: 15,
color: 'black',}}
image={require('./Icon/add_zb_icon1.png')}
shape='rectangle'
height={28}
width={100}
type="primary"
style={{margin:8}}
backgroundColors={['white', 'white']}
/>
</View>
);
}
}
initialRoute 和renderScene是導(dǎo)航器組件中必須聲明的屬性,initialRoute指定導(dǎo)航器的初始渲染組件,renderScene是渲染場景時的行為