項(xiàng)目連接: 93Laer/MyDemo
ReactNative使用手冊(cè)
關(guān)鍵詞:
- 場(chǎng)景(Scene):可簡(jiǎn)單的理解為一個(gè)界面中所有的組件構(gòu)成了這個(gè)界面,其實(shí)就是構(gòu)成了一個(gè)場(chǎng)景(Scene)
- Navigator:官方推薦的一個(gè)純JavaScript實(shí)現(xiàn)了一個(gè)導(dǎo)航棧柒爵,因此可以跨平臺(tái)工作,同時(shí)也便于定制的一個(gè)導(dǎo)航器。
Scene官方實(shí)例:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
export default class MyScene extends Component {
static defaultProps = {
title: 'MyScene'
};
render() {
return (
<View>
<Text>Hi! My name is {this.props.title}.</Text>
</View>
)
}
}
這就構(gòu)成了一個(gè)scene颂郎,感覺(jué)相當(dāng)于沒(méi)解釋谒获,但是為了再一次練習(xí)props,在項(xiàng)目中我還是再寫(xiě)了一次
使用Navigator:這里就不寫(xiě)了业簿,按照官方的實(shí)例跑一次發(fā)現(xiàn)報(bào)錯(cuò)瘤礁,報(bào)在'react-native'modules中找不到Navigator這個(gè)組件了,也提示了處理方法梅尤,但是我再看看官方文檔發(fā)現(xiàn)其實(shí)現(xiàn)在官方推薦的事是Navigator的教程,所以接下來(lái)直接進(jìn)入react-navigation庫(kù)學(xué)習(xí)
react-navigation庫(kù)使用:
安裝module:npm install --save react-navigation
最簡(jiǎn)單使用(直接使用StackNavigator加載界面)
/**
* 創(chuàng)建人:賴天兵
* 時(shí)間: 2018/2/24
* 簡(jiǎn)書(shū):http://www.reibang.com/u/2229fd214880
* 掘金:https://juejin.im/user/58647e21128fe1006d0f3f3e
* github:https://github.com/93Laer
* 描述:
*/
import { View, Text } from 'react-native';
import { StackNavigator } from 'react-navigation';
import React from 'react';
class NavigatorTest extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
)
}
}
export default StackNavigator({
AppHome: {screen: NavigatorTest}
});
注意:
- 1柜思、 路由名稱的大小寫(xiě)無(wú)關(guān)緊要,您可以使用小寫(xiě)字母home或大寫(xiě)字母Home巷燥,這取決于您赡盘。我們更喜歡大寫(xiě)我們的路線名稱。
- 2矾湃、
screen
組件唯一需要的配置是組件亡脑。您可以閱讀關(guān)于StackNavigator參考中可用的其他選項(xiàng)的更多信息。 - 3邀跃、在React Native中霉咨,從其中導(dǎo)出的組件App.js是您的應(yīng)用程序的入口點(diǎn)(或根組件) - 它是每個(gè)其他組件從中下降的組件。在你的應(yīng)用的根目錄下對(duì)組件進(jìn)行更多的控制通常比導(dǎo)出一個(gè)更有用StackNavigator拍屑,所以讓我們導(dǎo)出一個(gè)只呈現(xiàn)我們的組件StackNavigator(其實(shí)簡(jiǎn)單講就是在APP入口的時(shí)候就使用StackNavigator組件)途戒。
在StackNavigator中添加多條線路(注冊(cè)多個(gè)組件):也很簡(jiǎn)單,就直接上代碼解釋重點(diǎn)了
/**
* 創(chuàng)建人:賴天兵
* 時(shí)間: 2018/2/24
* 簡(jiǎn)書(shū):http://www.reibang.com/u/2229fd214880
* 掘金:https://juejin.im/user/58647e21128fe1006d0f3f3e
* github:https://github.com/93Laer
* 描述:
*/
import React from 'react';
import { View, Text } from 'react-native';
import { StackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
)
}
}
class DetailsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
</View>
);
}
}
export default StackNavigator({
//todo 1僵驰、直接展示
//AppHome: {screen: HomeScreen}
//todo 2喷斋、初始化多條線路,通過(guò)initialRouteName控制初始化那一個(gè)路由
Home: {
screen: HomeScreen,
},
Details: {
screen: DetailsScreen,
},
},
{
//通過(guò)initialRouteName來(lái)控制初始化哪一個(gè)路由
initialRouteName: 'Home',
}
);
解釋:其實(shí)就是在堆棧中多初始化了幾條線路蒜茴,然后通過(guò)initialRouteName
來(lái)控制來(lái)展示那一條星爪。
實(shí)現(xiàn)跳轉(zhuǎn)
問(wèn)題一:我們?cè)趺磸闹髀肪€(HomeScreen)移動(dòng)到細(xì)節(jié)(DetailsScreen)路線?
接下來(lái)我們將HomeScreen修改一下粉私,實(shí)現(xiàn)點(diǎn)擊按鈕跳轉(zhuǎn)詳情頁(yè)的功能顽腾,代碼如下:
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
//這里跳轉(zhuǎn)的頁(yè)面是我們已經(jīng)在StackNavigator中注冊(cè)了的,如果是沒(méi)注冊(cè)又會(huì)發(fā)生什么呢
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
)
}
}
問(wèn)題二:當(dāng)我們跳轉(zhuǎn)一個(gè)我們未在StackNavigator中注冊(cè)的界面又會(huì)發(fā)生什么呢诺核?
我們直接將跳轉(zhuǎn)代碼改成onPress={() => this.props.navigation.navigate('XXX')}
抄肖,看看會(huì)怎樣,結(jié)果就不展示了窖杀,其實(shí)就是沒(méi)有任何效果漓摩,所以我們跳轉(zhuǎn)的界面必須是在StackNavigator中注冊(cè)了的。
官方原話:如果我們this.props.navigation.navigate使用我們尚未定義的路由名稱進(jìn)行呼叫入客,則不會(huì)StackNavigator發(fā)生任何事情管毙。換句話說(shuō)腿椎,我們只能導(dǎo)航到已定義的路線StackNavigator- 我們無(wú)法導(dǎo)航到任意組件。
問(wèn)題三:那我們多次跳轉(zhuǎn)同一個(gè)注冊(cè)的界面锅风,又會(huì)出現(xiàn)什么呢酥诽?
- 首先我們將代碼改成
class HomeScreen extends React.Component {
render() {
return (
.
.
.
//這里跳轉(zhuǎn)的頁(yè)面是我們已經(jīng)在StackNavigator中注冊(cè)了的,如果是沒(méi)注冊(cè)又會(huì)發(fā)生什么呢
onPress={() => this.props.navigation.navigate('Details')}
/>
.
.
}
class DetailsScreen extends React.Component {
render() {
.
.
.
//這里跳轉(zhuǎn)的頁(yè)面是我們已經(jīng)在StackNavigator中注冊(cè)了的皱埠,如果是沒(méi)注冊(cè)又會(huì)發(fā)生什么呢
onPress={() => this.props.navigation.navigate('Details')}
/>
.
.
}
- 效果
總結(jié):多次打開(kāi)DetailsScreen頁(yè)面肮帐,會(huì)創(chuàng)建新的DetailsScreen頁(yè)面添加到堆棧
官方解釋:每次按“轉(zhuǎn)到詳細(xì)信息......再次”按鈕時(shí),它都會(huì)將新的屏幕推到頂部边器。這是我們?cè)瓉?lái)的比較document.location.href分崩離析的地方训枢,因?yàn)樵诰W(wǎng)絡(luò)瀏覽器中,這些不會(huì)被視為不同的路線忘巧,也不會(huì)將新條目添加到瀏覽器歷史記錄中 - navigate因?yàn)镾tackNavigator其行為更像網(wǎng)絡(luò)window.history.pushState:每次調(diào)用時(shí)navigate都會(huì)推送一個(gè)新的路由到導(dǎo)航堆棧恒界。
問(wèn)題四:我們?cè)鯓佑么a控制回到上一個(gè)頁(yè)面呢?其實(shí)這個(gè)就很簡(jiǎn)單了
- 首先我們?cè)贒etailsScreen中添加代碼
class DetailsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details again"
//這里跳轉(zhuǎn)的頁(yè)面是我們已經(jīng)在StackNavigator中注冊(cè)了的砚嘴,如果是沒(méi)注冊(cè)又會(huì)發(fā)生什么呢
onPress={() => this.props.navigation.navigate('Details')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
}
效果就不展示了十酣,和點(diǎn)擊返回按鈕一樣。
經(jīng)過(guò)問(wèn)題三和問(wèn)題四际长,你肯定會(huì)想到耸采,那如果我們有業(yè)務(wù)的邏輯是常見(jiàn)的要求是能夠返回多個(gè)屏幕 - 例如,如果您在堆棧中有幾個(gè)屏幕深度工育,并且想要將它們?nèi)砍坊氐降谝粋€(gè)屏幕虾宇。官方說(shuō)我們將在“建立一個(gè)簽名流”中討論如何做到這一點(diǎn)
不過(guò)暫時(shí)我還沒(méi)有找到解決辦法,知道請(qǐng)留言
使用路由傳參
跳轉(zhuǎn):
在上面的例子中我們跳轉(zhuǎn)是調(diào)用onPress={() => this.props.navigation.navigate('Details')}
而需要攜帶參數(shù)的跳轉(zhuǎn)如绸,其實(shí)也很簡(jiǎn)單嘱朽,無(wú)非就是跳轉(zhuǎn)多一個(gè)參數(shù),將需要傳遞的參數(shù)以一個(gè)對(duì)象的形式進(jìn)行傳遞
onPress={() => this.props.navigation.navigate('Details',{title:'這是主界面?zhèn)鬟f的title'})}
可以看出這里其實(shí)就是多了{title:'這是主界面?zhèn)鬟f的title'}
這個(gè)參數(shù)
使用:
如果你是像我這里一樣傳遞的是title怔接,那么將title設(shè)置給標(biāo)題欄搪泳,其實(shí)也很簡(jiǎn)單,在navigationOptions中調(diào)用navigation.state.params.title
設(shè)置headerTitle即可
//設(shè)置頂部導(dǎo)航欄的內(nèi)容
static navigationOptions = ({navigation, screenProps}) => ({
//標(biāo)題
headerTitle: navigation.state.params.title,
//設(shè)置跳轉(zhuǎn)頁(yè)面左側(cè)返回箭頭后面的文字,默認(rèn)是上一個(gè)頁(yè)面的標(biāo)題
headerBackTitle: null,
//頂部標(biāo)題欄的樣式
headerStyle: styles.headerStyle,
//頂部標(biāo)題欄文字的樣式
headerTitleStyle: styles.headerTitleStyle,
});
這里只是展示了部分navigationOptions 的參數(shù)設(shè)置扼脐,詳情見(jiàn)React Navigation或是
react-navigation使用技巧
注意:上面使用我們傳遞的參數(shù)由于navigationOptions已經(jīng)有navigation這個(gè)對(duì)象所以我們使用參數(shù)是調(diào)用navigation.state.params.title
岸军,那如果我們要在其他地方使用呢,則調(diào)用this.props.navigation.state.params.title
例如:
<Text>{this.props.navigation.state.params.title}</Text>
效果圖:
這里只是部分代碼展示谎势,完整代碼,見(jiàn)頂部項(xiàng)目
StackNavigator和Navigator相比有什么好處呢:
- 1杨名、新的導(dǎo)航庫(kù)無(wú)論從性能還是易用性上都要大大好于老的Navigator脏榆!這是官方原話
- 2、StackNavigator寫(xiě)起來(lái)更簡(jiǎn)單方便台谍,讀者 可以點(diǎn)擊Navigator自己對(duì)比须喂,尤其這點(diǎn)使用過(guò)Navigator和StackNavigator的人體會(huì)明顯
- 3、StackNavigator只能跳轉(zhuǎn)已注冊(cè)的界面,類似與安卓只能跳轉(zhuǎn)在清單文件中注冊(cè)的activity一樣坞生,而Navigator沒(méi)有這個(gè)規(guī)則仔役,但是必須將Navigator自身作為一個(gè)屬性相互傳遞,而StackNavigator至少不需要我們手動(dòng)傳遞(作為一個(gè)安卓開(kāi)發(fā)來(lái)說(shuō)是己,我更傾向StackNavigator)
喜歡請(qǐng)點(diǎn)贊又兵,或是關(guān)注,后續(xù)將完善發(fā)布更多的文章卒废,你的鼓勵(lì)就是我的動(dòng)力(程序員最大的動(dòng)力莫過(guò)于同行的鼓勵(lì))