title: 翻譯|React-navigation(1)
date: 2017-03-27 20:26:48
categories: 翻譯
這個React-native的導航系統(tǒng)可能已經(jīng)基本官方標配系統(tǒng)了.兩個月時間已經(jīng)積累了3000多的star.
教程可以參考這篇文章,這個文章作者老兄和我一樣很喜歡折騰.前面就參考了他的另一個導航教程,這次再來.
本文是翻譯的官方文檔.打算翻譯完
基本思路是有幾個注冊系統(tǒng),如果要在app中使用導航,必須要把組件注冊到對應(yīng)的系統(tǒng)中.
原文開始:你好!移動導航
使用React Navigation來構(gòu)建跨平臺導航
配置和安裝
首先要配置React Native系統(tǒng).接下來創(chuàng)建RN項目,添加react-navigation
# Create a new React Native App
#創(chuàng)建新RN APP
react-native init SimpleApp
cd SimpleApp
# Install the latest version of react-navigation from npm安裝最新版本
npm install --save react-navigation
# Run the new app運行,確保初始化正常
react-native run-android # or:
react-native run-ios

為了在Android和iOS之間共享代碼,刪除掉index.ios.js和index.andorid.js的實際代碼,使用import './App'來實現(xiàn)具體的代碼
現(xiàn)在來創(chuàng)建‘App.js’
Stack Navigator介紹
為了想使用stack navigation的概念,我們會使用StactkNavigator.(譯注:stack就是數(shù)據(jù)結(jié)構(gòu)的堆棧技術(shù),遵循后進先出的原理).每一個被到導航的screen(導航畫面)被放在堆棧的棧頂,返回時候,會從棧頂彈出對應(yīng)的組件.先看看一個screen的情況
//其實這個代碼沒有實現(xiàn)App.js,export的模式,注意
import React from 'react';
import {
AppRegistry,
Text,
} from 'react-native';
//導入stack導航組件
import { StackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',//在導航中顯示的標題內(nèi)容
};
render() {
//這里可以是導入的其他組件
return <Text>Hello, Navigation!</Text>;
}
}
//進行導航的注冊
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
});
AppRegistry.registerComponent('SimpleApp', () => SimpleApp);
title是staticnavigationOptions里配置的標題內(nèi)容,出現(xiàn)的界面看下面
添加新的導航畫面
再添加一個ChatScreen畫面
class ChatScreen extends React.Component {
static navigationOptions = {
title: 'Chat with Lucy',
};
render() {
return (
<View>
<Text>Chat with Lucy</Text>
</View>
);
}
}
在HomeScreen中添加一個button組件,使用routeName Chat關(guān)聯(lián)到ChatScreen.
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Hello, Chat App!</Text>
<Button
onPress={() => navigate('Chat')}
title="Chat with Lucy"
/>
</View>
);
}
}
我們正在使用從screen navigation prop獲得的導航函數(shù)轉(zhuǎn)向ChatScreen.但是這需要在StackNavigator中注冊.
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
Chat: { screen: ChatScreen },//新添加的screen
});
現(xiàn)在可以導航到ChatScreen,也可以返回了.
傳遞參數(shù)
在ChatScreen中硬編碼標題不是好辦法,可以在導航的時候傳遞參數(shù).首先編輯一下HomeScreen組件,傳遞name參數(shù)到路由中.
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Hello, Chat App!</Text>
<Button
onPress={() => navigate('Chat', { user: 'Lucy' })}
title="Chat with Lucy"
/>
</View>
);
}
}
我們可以編輯ChatScreen組件顯示的name參數(shù),這個參數(shù)通過route來傳遞.
class ChatScreen extends React.Component {
static navigationOptions = {
// Nav options can be defined as a function of the navigation prop:
title: ({ state }) => `Chat with ${state.params.user}`,
};
render() {
// The screen's current route is passed in to `props.navigation.state`:
const { params } = this.props.navigation.state;
return (
<View>
<Text>Chat with {params.user}</Text>
</View>
);
}
}
現(xiàn)在當你導航到Chat screen的時候,可以看到名字了.在HomeScreen中改變name,看看變化.
巢式導航
在移動應(yīng)用中組合各種形式的導航是非常普遍的.React Navigation中的router和navigators是組合式的,如此以來可以允許我們定義非常復雜的導航系統(tǒng).
Tab Navigator的介紹
我們在App.js中創(chuàng)建TabNavigator:
class RecentChatsScreen extends React.Component {
render() {
return <Text>List of recent chats</Text>
}
}
class AllContactsScreen extends React.Component {
render() {
return <Text>List of all contacts</Text>
}
}
const MainScreenNavigator = TabNavigator({
Recent: { screen: RecentChatsScreen },
All: { screen: AllContactsScreen },
});
如果MainScreenNavigation作為頂層的導航組件來渲染,看起來是這個樣子的:
在屏幕中構(gòu)造一個巢式導航器
我們想讓這些tabs在app的第一屏顯示,但是堆棧中的新的screen會覆蓋tabs.
在前一步驟設(shè)置的StackNavigator中添加tabs作為頂級導航
const SimpleApp = StackNavigator({
Home: { screen: MainScreenNavigator },
Chat: { screen: ChatScreen },
});
因為MainScreenNavigator作為screen,可以傳遞navigationOtions參數(shù):
MainScreenNavigator.navigationOptions = {
title: 'My Chats',
};
在每一個tabs中添加鏈接到chat的按鈕:
<Button
onPress={() => this.props.navigation.navigate('Chat', { user: 'Lucy' })}
title="Chat with Lucy"
/>
現(xiàn)在我們在每個導航器彼此之間做了配置,可以在導航界面之間切換.
配置頭部
在前面的例子中,我們用StactNavigator創(chuàng)建了幾個screen.
當我們導航到chat screen,我們通過navigate 函數(shù)傳遞特定的參數(shù)到新的導航界面.例如,我們想給chat screen提供一個人名:
this.props.navigation.navigate('Chat', { user: 'Lucy' });
user參數(shù)可以在chat screen中獲取到:
class ChatScreen extends React.Component {
render() {
const { params } = this.props.navigation.state;
return <Text>Chat with {params.user}</Text>;
}
}
設(shè)定頭部標題
接著來,可以在screen 參數(shù)中配置頭部的標題
class ChatScreen extends React.Component {
static navigationOptions = {
// // Title may be a simple string:
// title: 'Hello',
// Or the title string may be a function of the
navigation prop:可以是prop的函數(shù)解析
title: ({ state }) => `Chat with ${state.params.user}`
};
...
}
添加右側(cè)的按鈕
可以在option中添加定制的右側(cè)按鈕
static navigationOptions = {
header: {
right: <Button title="Info" />,
},
...
和title一樣,headeroption可以定義為prop的一個函數(shù).讓我們來基于導航參數(shù)渲染一個不同的按鈕,設(shè)定為點擊時調(diào)用navigation.setParams:
static navigationOptions = {
title: ({ state }) => {
if (state.params.mode === 'info') {
return `${state.params.user}'s Contact Info`;
}
return `Chat with ${state.params.user}`;
},
header: ({ state, setParams }) => {
// The navigation prop has functions like setParams, goBack, and navigate.
let right = (
<Button
title={`${state.params.user}'s info`}
onPress={() => setParams({ mode: 'info' })}
/>
);
if (state.params.mode === 'info') {
right = (
<Button
title="Done"
onPress={() => setParams({ mode: 'none' })}
/>
);
}
return { right };
},
...
現(xiàn)在頭部可以和screen的路由state進行交互了.
第一部分就這些.