9
6

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-navigationでページ遷移を検知して処理をはさむ

Last updated at Posted at 2017-09-21

背景

  • react-navigationを使っていてページ遷移を契機に処理を実行したい
  • 例えば特定のページだけAndroidのバックボタンを制御したいようなときに、ページ遷移ではcomponentWillUnmount等通らないので解除するタイミングがない
    • 次のページのcomponentWillMountで解除してもいいが戻られた時に制御が外れてしまう

対応サンプル

  • react-navigationの機能でページ遷移を検知することができた
index.android.js
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
import AppNavigator, { disabledBackScreens } from './app/navigators/AppNavigator';
import { disabledAndroidBack, abledAndroidBack } from './app/utils/Util';

class ReactNativeSample extends Component {
  render() {
    // onNavigationStateChangeに渡す関数がページ遷移の度に呼ばれる
    return <AppNavigator onNavigationStateChange={this.onNavigationStateChange} />;
  }

  // 引数のサンプルは後述
  onNavigationStateChange(prevState, currentState, action) {
      // routesは遷移履歴の配列
    const routes = currentState.routes;
    // 現在の画面は配列の最後、routeNameで画面名がとれる
    const currentRouteName = routes[routes.length - 1].routeName;
    // ここの例では戻るを無効にしたい画面か判断しそれぞれ処理を呼んでいる
    disabledBackScreens.includes(currentRouteName) ? disabledAndroidBack() : abledAndroidBack();
  }
}

AppRegistry.registerComponent('ReactNativeSample', () => ReactNativeSample);
  • onNavigationStateChangeで受け取る引数のサンプル
  • スクリーンショット 2017-09-22 1.09.15.png
app/navigators/AppNavigator.js
import { StackNavigator } from 'react-navigation';
import SampleAScreen from '../containers/SampleAScreen';
import SampleBScreen from '../containers/SampleBScreen';
import SampleCScreen from '../containers/SampleCScreen';
import SampleDScreen from '../containers/SampleDScreen';
import SampleEScreen from '../containers/SampleEScreen';

const AppNavigator = StackNavigator({
  SampleA: { screen: SampleAScreen },
  SampleB: { screen: SampleBScreen },
  SampleC: { screen: SampleCScreen },
  SampleD: { screen: SampleDScreen },
  SampleE: { screen: SampleEScreen },
});

export const disabledBackScreens = ['SampleB', 'SampleD'];
export default AppNavigator;
app/utils/Util.js
import { BackHandler } from 'react-native'

// trueを返すとバックボタンを押した時のデフォルトの動きをキャンセルしてくれる
const androidBackHandler = () => true

export const disabledAndroidBack = () =>{
  BackHandler.addEventListener('hardwareBackPress', androidBackHandler)
}

export const abledAndroidBack = () =>{
  // 第二引数はaddEventListenerした時の第二引数と同じものでないとダメ
  BackHandler.removeEventListener('hardwareBackPress', androidBackHandler)
}

まとめ

  • ページ遷移の度に処理をかませることが出来るので何かと便利そう
9
6
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
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?