3
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

React Native 入門してみた② 画面遷移編

Last updated at Posted at 2019-06-03

React Native 入門してみた① 環境構築編+HelloWorldにつづいて今回は画面遷移についての入門です。

画面遷移

画面遷移出来ないと話にならないので学習。
候補として下記ライブラリがありましたが、GithubStar数が多く扱いやすそうなどの理由からreact-navigationを画面遷移を実装します。

構成は前回の記事同様、TypeScript構成です。
実装には、下記サイトを参考にさせて頂きました。

インストール

React Navigationをインストールします。
react-native-gesture-handlerも必要なようなので一緒にインストールします。

 npm install --save react-navigation@2.0.1 react-native-gesture-handler

何故@2.0.1なのかは下記、問題1. ビルドエラーを参考下さい。

実装

構造

├── App.tsx
├── app.json
├── assets
│   ├── icon.png
│   └── splash.png
├── babel.config.js
├── package-lock.json
├── package.json
├── src
│   ├── navigator
│   │   └── index.ts
│   └── screens
│       ├── Main.tsx
│       ├── Modal.tsx
│       └── Push.tsx
└── tsconfig.json

src/navigator/index.tsに画面の遷移処理を記載します。
screens/配下のコンポーネントが各画面です。

ナビゲーションの実装

navigator/index.ts

index.ts
import { createStackNavigator, NavigationScreenProp } from 'react-navigation'

//画面
import Main from '../screens/Main'
import Push from '../screens/Push'
import Modal from '../screens/Modal'

export interface HomeScreenProps {
  navigation: NavigationScreenProp<any, any>
};

export const MainNavigation = createStackNavigator(
  {
    Main: { screen: Main },
    Push: { screen: Push },
  },
  { initialRouteName: 'Main', mode: 'card', headerMode: 'none' }
)

export default createStackNavigator(
  {
    MainNavigation: { screen: MainNavigation },
    Modal: { screen: Modal },
  },
  { initialRouteName: 'MainNavigation', mode: 'modal', headerMode: 'none' },
)

ここでは各画面の遷移処理を記載します。
画面はscreens/配下に作成します。
createStacknavigatorを使用して画面遷移を作成します。
initialRouteNameで初期画面を設定し、画面遷移の方法はmodeを指定して変更します。
modeはレンダリングと遷移のスタイルを定義します。
modalcardの種類が存在しそれぞれ下記になります。

  • modal: 標準のiOSとAndroidの画面遷移を使用します。 これがデフォルトです。
  • card: 画面を下からスライドさせます。iOSでのみ動作し、Androidでは動作しません。

続いて、各画面の実装します
screens/Main.tsx

Main.tsx
import React, {Component} from 'react';
import { Container, View, Header, Left, Body, Right, Button, Title, Text } from 'native-base';

import {HomeScreenProps} from '../navigator'

export default class Main extends Component<HomeScreenProps> {
  push = () => {
    const { navigation } = this.props
    navigation.navigate('Push')
  }
  modal = () => {
    const { navigation } = this.props
    navigation.navigate('Modal')
  }
  render() {
    return (
      <Container>
        <Header>
          <Left />
          <Body>
            <Title>メイン</Title>
          </Body>
          <Right />
        </Header>
        <View>
          <Button small iconRight  transparent primary onPress={this.push}>
            <Text>プッシュ表示</Text>
          </Button>
        </View>
        <View>
          <Button small iconRight  transparent primary onPress={this.modal}>
            <Text>モーダル表示</Text>
          </Button>
        </View>
      </Container>
    );
  }
}

メイン画面の実装です。
this.props.navigation.navigateを使用することで画面遷移出来ます。
.navigate('Push')でPush画面に遷移、PushをModalとすることで、Modal画面に遷移出来ます。

screens/PUsh.tsx

Push.tsx
import React, {Component} from 'react';
import { Container, Header, Left, Body, Right, Button, Icon, Title } from 'native-base';

import {HomeScreenProps} from '../navigator'

export default class Push extends Component<HomeScreenProps> {
  render() {
    return (
      <Container>
        <Header>
          <Left>
            <Button transparent onPress={() => this.props.navigation.goBack()}>
              <Icon name='arrow-back' />
            </Button>
          </Left>
          <Body>
            <Title>プッシュ</Title>
          </Body>
          <Right />
        </Header>
      </Container>
    );
  }
}

this.props.navigation.goBack()で前の画面に戻ることが出来ます。

App.tsx

App.tsx
import React, { Component } from 'react';
import Navigator from './src/navigator';

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

ルート(親)コンポーネントでは、<Navigaror/> (src/navigator/index.ts)コンポーネントをrenderします。

ハマったポイント

実装中にハマったポイントです。

問題1. ビルドエラー

Tried to register two views with the same name RNGestureHandlerButton

register
    ReactNativeViewConfigRegistry.js:76:4

問題2. TypeScript対応時の各ページのPropsについて

type Props = {}
export default class Main extends Component<Props> {
...

として場合、 this.props.navigation.navigate('Push')でエラーとなってします。
そこで、react-navigationからinterfaceを作成する

import { createStackNavigator,NavigationScreenProp} from 'react-navigation'

export interface HomeScreenProps {
  navigation: NavigationScreenProp<any,any>
}

上記interfaceを各画面のPropsに追加することで対応できます
typescript - Add strong typing for react navigation props - Stack Overflow

Next

続いては、React Native 入門してみた③ Httpアクセスです。

3
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?