1. 程式人生 > >React Navigation 入門(一)

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 的定義。

其中 HomeDetail 是自定義的名稱,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(屬性) 這篇文章中,還專門寫過,自己都差點忘記了。

它們不過是不同的寫法,效果是完全一致的,圖就不貼了。先暫時寫這麼多,等我繼續研究研究再更新吧。