title: 翻譯|React-navigation(1)
date: 2017-03-27 20:26:48
categories: 翻譯
這個React-native的導航系統可能已經基本官方標配系統了.兩個月時間已經積累了3000多的star.
教程可以參考這篇文章,這個文章作者老兄和我一樣很喜歡折騰.前面就參考了他的另一個導航教程,這次再來.
本文是翻譯的官方文檔.打算翻譯完
基本思路是有幾個注冊系統,如果要在app中使用導航,必須要把組件注冊到對應的系統中.
原文開始:你好!移動導航
使用React Navigation來構建跨平臺導航
配置和安裝
首先要配置React Native系統.接下來創建RN項目,添加react-navigation
# Create a new React Native App
#創建新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'
來實現具體的代碼
現在來創建‘App.js’
Stack Navigator介紹
為了想使用stack
navigation的概念,我們會使用StactkNavigator
.(譯注:stack就是數據結構的堆棧技術,遵循后進先出的原理).每一個被
到導航的screen(導航畫面)被放在堆棧的棧頂,返回時候,會從棧頂彈出對應的組件.先看看一個screen的情況
//其實這個代碼沒有實現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',//在導航中顯示的標題內容
};
render() {
//這里可以是導入的其他組件
return <Text>Hello, Navigation!</Text>;
}
}
//進行導航的注冊
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
});
AppRegistry.registerComponent('SimpleApp', () => SimpleApp);
title
是staticnavigationOptions
里配置的標題內容,出現的界面看下面

添加新的導航畫面
再添加一個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
關聯到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
獲得的導航函數轉向ChatScreen
.但是這需要在StackNavigator
中注冊.
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
Chat: { screen: ChatScreen },//新添加的screen
});
現在可以導航到ChatScreen,也可以返回了.

傳遞參數
在ChatScreen
中硬編碼標題不是好辦法,可以在導航的時候傳遞參數.首先編輯一下HomeScreen
組件,傳遞name
參數到路由中.
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
參數,這個參數通過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>
);
}
}
現在當你導航到Chat screen的時候,可以看到名字了.在HomeScreen
中改變name
,看看變化.

巢式導航
在移動應用中組合各種形式的導航是非常普遍的.React Navigation中的router和navigators是組合式的,如此以來可以允許我們定義非常復雜的導航系統.
Tab Navigator的介紹
我們在App.js
中創建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
作為頂層的導航組件來渲染,看起來是這個樣子的:

在屏幕中構造一個巢式導航器
我們想讓這些tabs在app的第一屏顯示,但是堆棧中的新的screen會覆蓋tabs.
在前一步驟設置的StackNavigator
中添加tabs作為頂級導航
const SimpleApp = StackNavigator({
Home: { screen: MainScreenNavigator },
Chat: { screen: ChatScreen },
});
因為MainScreenNavigator
作為screen,可以傳遞navigationOtions
參數:
MainScreenNavigator.navigationOptions = {
title: 'My Chats',
};
在每一個tabs中添加鏈接到chat的按鈕:
<Button
onPress={() => this.props.navigation.navigate('Chat', { user: 'Lucy' })}
title="Chat with Lucy"
/>
現在我們在每個導航器彼此之間做了配置,可以在導航界面之間切換.

配置頭部
在前面的例子中,我們用StactNavigator創建了幾個screen.
當我們導航到chat screen,我們通過navigate 函數傳遞特定的參數到新的導航界面.例如,我們想給chat screen提供一個人名:
this.props.navigation.navigate('Chat', { user: 'Lucy' });
user
參數可以在chat screen中獲取到:
class ChatScreen extends React.Component {
render() {
const { params } = this.props.navigation.state;
return <Text>Chat with {params.user}</Text>;
}
}
設定頭部標題
接著來,可以在screen 參數中配置頭部的標題
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的函數解析
title: ({ state }) => `Chat with ${state.params.user}`
};
...
}

添加右側的按鈕
可以在option中添加定制的右側按鈕
static navigationOptions = {
header: {
right: <Button title="Info" />,
},
...

和title
一樣,header
option可以定義為prop的一個函數.讓我們來基于導航參數渲染一個不同的按鈕,設定為點擊時調用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 };
},
...
現在頭部可以和screen的路由state進行交互了.

第一部分就這些.