React.js
Pocket

以前書いた時から、他にもライブラリを使ってみました。

ReactNativeでページ遷移(ルーティング)を実装する

以前書いた記事では最後に「React Native Navigation」というライブラリを使いましたが、いろいろとツラいことがありましたので、今回は他の2つを試してます。

React Native Navigationは高機能は反面、導入するためにXcodeの設定が必要ですが、今回試した2つはインストールするだけで使えますし、基本的なページ遷移のUIは備わっています。

もくじ
  1. React Native Router Flux
  2. React Navigation

React Native Router Flux

React Native Router FluxはReact Routerを使ってる感覚で実装できます。

react-native-router-flux

まずはインストールyarnかnpm好きな方で。

yarn add react-native-router-flux

index.ios.jsを編集するのと、「component」ディレクトリを作って、その中にApp.js、PageA.js、PageB.js、PageC.jsをサンプルとして作ります。

index.ios.js

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

import App from './component/App.js'

export default class rnsample extends Component {
  render() {
    return (
      <App />
    );
  }
}

AppRegistry.registerComponent('rnsample', () => rnsample);

component/App.js

import React from 'react';
import {
  StyleSheet,
} from 'react-native';
import {
  Scene,
  Router,
  Actions
} from 'react-native-router-flux';

import PageA from './PageA.js'
import PageB from './PageB.js'
import PageC from './PageC.js'

const scenes = Actions.create(
  <Scene key="root">
    <Scene key="PageA" initial component={PageA} title="PageA" />
    <Scene key="PageB" component={PageB} title="PageB" />
    <Scene key="PageC" component={PageC} title="PageC" />
  </Scene>
);

class App extends React.Component {
  render() {
    return <Router scenes={scenes}/>
  }
}

export default App;

component/PageA.js

import React from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  StyleSheet,
} from 'react-native';
import {
  Actions,
} from 'react-native-router-flux';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  linkText: {
    fontSize: 32,
    color: 'rgb(95, 177, 237)',
  },
});

const PageA = () => (
  <View style={styles.container}>
    <Text>PageA</Text>
    <TouchableOpacity onPress={Actions.PageB}>
      <Text style={styles.linkText}>Link</Text>
    </TouchableOpacity>
  </View>
);
export default PageA;

component/PageB.js

import React from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  StyleSheet,
} from 'react-native';
import {
  Actions,
} from 'react-native-router-flux';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  linkText: {
    fontSize: 32,
    color: 'rgb(95, 177, 237)',
  },
});

const PageB = () => (
  <View style={styles.container}>
    <Text>PageB</Text>
    <TouchableOpacity onPress={Actions.PageC}>
      <Text style={styles.linkText}>Link</Text>
    </TouchableOpacity>
  </View>
);
export default PageB;

component/PageC.js

import React from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  StyleSheet,
} from 'react-native';
import {
  Actions,
} from 'react-native-router-flux';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  linkText: {
    fontSize: 32,
    color: 'rgb(95, 177, 237)',
  },
});

const PageC = () => (
  <View style={styles.container}>
    <Text>PageC</Text>
  </View>
);
export default PageC;

こんな感じになります。

react-native-router-flux

ページ遷移もしてくれるし、スワイプ操作で戻る動きも実装できています。

こちらの記事を参考にしてやってみました。

React Native Router Fluxを使ってみませんか・・・?

Qiita @YutamaKotaro

タブの実装方法も書かれています。この記事通りやれば、タブの動きもできました。

React Navigation

React Navigationを知ったのはこちらの記事。

React.js × React Native meetup アンケート質問に答えたい

Qiita @janus_wel

最後の「RN での navigation はどう実現しているか ?」で一番上に書かれています。コミュニティ推しと書かれているので、使ってみました。

React Navigation

まずは、インストール

yarn add react-navigation

先ほど作ったcompornent以下のファイルを修正していきます。

App.js

import React from 'react';
import {
  Button,
  ScrollView,
  Text,
} from 'react-native';
import {
  StackNavigator,
} from 'react-navigation';

import PageA from './PageA.js'
import PageB from './PageB.js'
import PageC from './PageC.js'

const PageAScreen = ({ navigation }) => (
  <PageA
    navigation={navigation}
  />
);
PageAScreen.navigationOptions = {
  title: 'PageA',
};

const PageBScreen = ({ navigation }) => (
  <PageB
    navigation={navigation}
  />
);
PageBScreen.navigationOptions = {
  title: 'PageB',
};

const PageCScreen = ({ navigation }) => (
  <PageC
    navigation={navigation}
  />
);
PageCScreen.navigationOptions = {
  title: 'PageC',
};

const App = StackNavigator({
  PageA: {
    screen: PageAScreen,
  },
  PageB: {
    path: 'pageb',
    screen: PageBScreen,
  },
  PageC: {
    path: 'pagec',
    screen: PageCScreen,
  },
});

export default App;

PageA.js

import React from 'react';
import {
  View,
  Text,
  Button,
  TouchableOpacity,
  StyleSheet,
} from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  linkText: {
    fontSize: 32,
    color: 'rgb(95, 177, 237)',
  },
});

const PageA = ({navigation}) => (
  <View style={styles.container}>
    <Text>PageA</Text>
    <Button
      onPress={() => navigation.navigate('PageB')}
      title="PageB"
    />
  </View>
);
export default PageA;

PageB.js

import React from 'react';
import {
  View,
  Text,
  Button,
  TouchableOpacity,
  StyleSheet,
} from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  linkText: {
    fontSize: 32,
    color: 'rgb(95, 177, 237)',
  },
});

const PageB = ({navigation}) => (
  <View style={styles.container}>
    <Text>PageB</Text>
    <Button
      onPress={() => navigation.navigate('PageC')}
      title="PageC"
    />
  </View>
);
export default PageB;

PageC.js

import React from 'react';
import {
  View,
  Text,
  Button,
  TouchableOpacity,
  StyleSheet,
} from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  linkText: {
    fontSize: 32,
    color: 'rgb(95, 177, 237)',
  },
});

const PageC = () => (
  <View style={styles.container}>
    <Text>PageC</Text>
  </View>
);
export default PageC;

すると、こうなります。

react-navigation

React Navigationのいいところは、ページごとにシャドウをつけてくれるので、ページが上に重なっていくようなネイティブのUIっぽくなるとこですかね。React Native Router FluxのGif動画と比較すると分かると思いますが、React Native Router Fluxはシャドウがないです。

他にもタブやドロワーなどもあります。詳しくはドキュメントを見れば分かるかと思います。

React Navigation Docs

さいごに

どちらのソースコードをみても、けっこう分かり易かったと思います。

どちらかといえば、React Navigationの方が、コミュニティ推しだったり、よりネイティブっぽい感じはするので、いいかなと思っています。ただReact Navigationはググラビリティが非常に悪い…。

Pocket

Category : Tag :