React Navigation 入門(一)
RN 版本:0.50
操作環境:Windows 10
React Navigation 版本:1.0.0-beta.20
前言
Navigator(導航器)是用來進行場景(頁面)切換的元件,但是由於它的各種缺陷,從 0.44 開始,就被 fb 移除了,並且推薦大家使用更方便的 React Navigation 。
React Navigation 改進並取代了多個導航庫,目前仍然在繼續完善中。它包含 StackNavigator、TabNavigator 和 DrawerNavigator,你還可以自定義導航器。由於我也是跟著官方文件剛剛學,打算邊學邊總結加深印象,同時給大家一個參考(英文文件我看著實在很累)。不出意外,應該會寫上好幾篇。
StackNavigator 實現最基本的頁面跳轉
StackNavigator 一次渲染一個螢幕,並提供螢幕之間的轉換。當一個新的螢幕開啟時,它被放在棧頂位置。
首先安裝 React Navigation:
yarn add react-navigation
然後匯入到專案中(這裡我們只用到了 StackNavigator):
import {StackNavigator} from 'react-navigation';
下面的例子來源於 官網,我在其基礎上加以說明,直接上程式碼。
const HomeScreen = () => (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>Home Screen</Text>
</View>
);
const DetailScreen = () => (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>Detail Screen</Text>
</View >
);
const RootNavigator = StackNavigator({
Home: {
screen: HomeScreen
},
Detail: {
screen: DetailScreen
}
});
export default RootNavigator;
兩個 View 分別展示了一行文字,這裡主要講一下 RootNavigator 的定義。
其中 Home
和 Detail
是自定義的名稱,screen
屬性是要顯示在頁面上的檢視元件。StackNavigator
顧名思義,棧導航器,這裡寫的 Home
頁面就是第一個入棧的,也是程式執行時第一個顯示的。
我們將其匯入並註冊,
import RootNavigator from './RootNavigator';
AppRegistry.registerComponent('BlogDemo', () => RootNavigator);
執行。
可以看到第一個頁面已經顯示出來了,並且自帶了一個類似 ToolBar 的東西,這個東西怎麼去掉,我還沒有研究到。
好了,這不是重點。
下面說一說如何跳轉到 Detail
頁面。我們在 HomeScreen
中稍作修改,
const HomeScreen = ({navigation}) => (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>Home Screen</Text>
<Button
onPress={() => navigation.navigate('Detail')}
title='Go to Detail'/>
</View>
);
可以看到在方法的引數中添加了一個 {navigation}
的引數,暫時先不需要知道它的具體工作原理,只要知道在某個頁面被 StackNavigator
載入的時候,會自動分配一個 navigation
屬性就可以了。這個屬性就是用來驅動頁面之間的跳轉的。navigate(routeName, params, action)
這個方法有三個引數,目前只說第一個。routeName
表示已經註冊過的目標路由的名稱,也就是我們打算跳轉到的頁面,這裡就是 Detail
,由於是自定義的名稱,書寫的時候不要寫錯了。
為了美觀(大概吧),我們再給兩個 ‘ToolBar’ 加上標題。
const RootNavigator = StackNavigator({
Home: {
screen: HomeScreen,
navigationOptions: {
headerTitle: 'Home'
}
},
Detail: {
screen: DetailScreen,
navigationOptions: {
headerTitle: 'Detail'
}
}
});
然後跑起來:
Detail
頁面還自帶了一個返回按鈕,是不是很神奇?
最後呢,一般來說,每個頁面都是單獨寫在一個 js 檔案中的,這樣的話,該如何取到 navigation
引數並進行頁面跳轉呢?
我們之前說過了,在某個頁面被 StackNavigator
載入的時候,會自動分配一個 navigation
屬性。所以如果我們把 HomeScreen 和 DetailScreen 單獨拿出來,可以這麼寫,以 HomeScreen 為例:
export default class HomeScreen extends Component {
constructor(props) {
super(props);
}
render() {
return <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>Home Screen</Text>
<Button
onPress={() => this.props.navigation.navigate('Detail')}
title='Go to Detail'/>
</View>;
}
}
沒有錯,我們可以直接通過 this.props.navigation
獲取到它,然後執行 navigate()
方法。
但是,官網卻是這麼寫的(程式碼似乎和本節不一致,因為是在另一個地方粘的,請先忽略,這不是重點):
class HomeScreen extends React.Component {
render() {
const {navigate} = this.props.navigation;
return (
<View>
<Text>This is the home screen of the app</Text>
<Button
onPress={() => navigate('Profile', {name: 'Brent'})}
title="Go to Brent's profile"
/>
</View>
)
}
}
第一眼看上去我懵逼了, const {navigate} = this.props.navigation;
是個什麼鬼?
仔細想想,其實這就是解構賦值嘛。我在 React Native 入門(五) - Props(屬性) 這篇文章中,還專門寫過,自己都差點忘記了。
它們不過是不同的寫法,效果是完全一致的,圖就不貼了。先暫時寫這麼多,等我繼續研究研究再更新吧。