react-native-router-fluxのonRightをカスタマイズする
2019-03-15

react-native-router-fluxのonRightをカスタマイズする

react-native-router-fluxの小ネタです。

react-native-router-fluxで毎日頭を悩ませています。
うーん、なんだろう。。。初見は使いやすそうなんですが、いざ本番となるといろいろ制約があって悩ましいライブラリですね。

今回はアプリのNavBarの右側にあるボタンをクリックした時に、次の画面にpropsを渡したいようなユースケースを想定しています。例えば参照画面から編集画面に移動するときなどです。
ボタンは次のイメージのような感じです。

この時react-native-router-fluxはonRightを発火するのですが、これに動的に値を渡すために少し工夫が必要でした。

通常のonRightの定義方法

「プロフィール」と「プロフィール編集」ページを想像してみましょう。「プロフィール」ページの編集ボタンをクリックすると「プロフィール編集」ページに移動します。この時、react-native-router-fluxのActionsプロフィールIDを渡して次の画面で利用できるようにしたいです。

次のコードは通常のRouter設定です。
onRightSceneと一緒に定義してあり、期待通り「プロフィール編集」しますが、プロフィールIDを値を渡すことはできません。

// AppRoute.tsx
  ...
  <Scene 
    key="page_profile" 
    component={Profile} 
    title="プロフィール"
    onRight={() => Actions.page_profile_edit()} 
    rightTitle="Edit"
  />
  <Scene 
    key="page_profile_edit" 
    component={ProfileEdit} 
    title="プロフィール編集"
  />
  ...

onRightをComponentの中で定義する

onRightにプロフィールIDを渡すためには、「プロフィール」ページの中でonRightハンドラを上書きして、IDを渡せるようにしなければなりません。
onRightはpropsで渡されてくるnavigation.setParams()にて置き換えできるので、componentWillMountでコンポーネントがMountされた時に上書きしましょう。

// Profile.tsx
export Profile extends React.Component<ProfileProps, {}> {
  componentWillMount() {
    this.props.navigation.setParams({
      'onRight': this.onRight,
    });
  }
  private onRight = () => {
    console.log('Press onRight!!');
    // ここでActionsにプロフィールIDを渡す
    Actions.page_profile_edit({ profileId: 1 });
  }}
  ...
}

Routerの方のonRightは動かないようにしておきます。

// AppRoute.tsx
  ...
  <Scene 
    key="page_profile" 
    component={Profile} 
    title="プロフィール"
-    onRight={() => Actions.page_profile_edit()} 
+    onRight={() => undefined} 
    rightTitle="Edit"
  />
  ...

TypeScriptで型付けする場合は@types/react-navigationNavigationScreenPropを使います。

// Profile.tsx
import { NavigationScreenProp } from 'react-navigation';

interface ProfileProps {
  navigation: NavigationScreenProp<any, any>;
}

export Profile extends React.Component<ProfileProps, {}> {
  componentWillMount() {
    this.props.navigation.setParams({
      'onRight': this.onRight,
    });
  }
  ...
}

これでonRightをカスタマイズすることができました。

。。。大変。

以上