LoginSignup
2
3

More than 5 years have passed since last update.

React NativeでEventEmitterを利用してナビゲーションのボタンイベントを検知する

Posted at

ReactNativeのナビゲーションボタンはコンポーネントと独立しているので、コンポーネントをまたいでイベントを処理する必要がある。NavigationコンポーネントでReduxのStateを監視しても良いが、単純にイベントを聞く方が個人的にはすっきりすると思う。 (Eventの多用は混乱を招くので注意しないといけませんが)

私はExNavigatorを利用しているので、これを用いて説明します。

Router.jsでEventEmitterのインスタンスを持ちます。そして、ボタンを押すとeventをemitする仕組みです。

import React, {View, WebView} from 'react-native';
import ExNavigator from '@exponent/react-native-navigator';
import ExSceneConfigs from '@exponent/react-native-navigator/ExSceneConfigs';
import EventEmitter from 'EventEmitter';

let eventEmitter = new EventEmitter();

let Router = {
  getNewBlockerRoute(){

    return {
      renderScene(navigator) {
        let NewBlocker = require('./containers/NewBlocker').default;
        return <NewBlocker navigator={navigator} type="new" events={eventEmitter}/>;
      },

      configureScene(nav){
        return ExSceneConfigs.ZoomFromFront;
      },
      getTitle(){
        return "New Blocker";
      },
      renderLeftButton(navigator){
        let CloseButton = require('./components/CloseButton').default;
        return <CloseButton navigator={navigator} onCloseButtonPress={() => eventEmitter.emit('closeButtonEvent') }/>
      },
      renderRightButton(navigator){
        let SaveBlockerButton = require('./containers/SaveBlockerButton').default;
        return <SaveBlockerButton navigator={navigator} type="new" onSaveButtonPress={() => eventEmitter.emit('saveButtonEvent') }/>
      }
    }
  },


}

module.exports = Router;

Closeボタンでは、propsを実行するだけ。

import React, { View, Text, Image } from 'react-native';
import Styles from './Styles';
import Button from 'react-native-button';

let CloseButton = React.createClass({

  onPressClose(){
    const { navigator, onCloseButtonPress } = this.props;
    if(typeof onCloseButtonPress === "function"){
      onCloseButtonPress();
    }
    navigator.pop();
  },

  render(){
    return (
      <Button onPress={this.onPressClose}>
        <Image source={require('../assets/images/close.png')} style={Styles.exClose} />
      </Button>
    );
  }
});

export default CloseButton;

そして、これをListenしたいComponentで定義する。

import Subscribable from 'Subscribable'; // unmount時にremoveなどのsubscriptionの処理をしてくれる

let NewBlocker = React.createClass({

  mixins: [ Subscribable.Mixin ], // Mixinで利用できるようになる。.Mixinを忘れずに

  componentDidMount(){
    this.addListenerOn(events, 'closeButtonEvent', this.stopLoading);
    this.addListenerOn(events, 'saveButtonEvent', this.stopLoading);  
    },  

  // emitされるたびに呼ばれる。
  stopLoading(){
    this.refs.webview.stopLoading();
  },

最初に言ったようにeventの多用は混乱します。私はRoute管理だけに利用しています。

2
3
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
2
3