react-native-router-fluxの小ネタです。
前回の話はこちら。
前回はアプリの NavBar の右側にあるボタン(以下、RightButton)をクリックした時に、次の画面に props を渡したいようなユースケースを想定していましたが、今回は RightButton を props の条件で出し分けしたいと思います。
次のような手順で実現できそうです。
- PageComponent 内部で RightButton を出す
- RightButton をタップした時に、Component 内部のタップハンドラ(private function)を実行する
- 外部からの props の値で RightButton を出し分けする
コードは全て TypeScript です。
PageComponent 内部で RightButton を出す
RightButton の追加方法はいくつかあるのですが、今回は PageComponent に static なnavigationOptions
プロパティを追加して、この中で RightButton 用の Component を定義します。
この方法というものがいくつかあって、それぞれ期待する動きをしないので辛いです。
// ...
import { NavigationScreenProps } from "react-navigation";
class Page extends React.Component<State, Props> {
static navigationOptions = ({ navigation }: NavigationScreenProps) => {
return {
// ここにRightButtonのComponentを渡す
headerRight: <Button title="+1" />,
};
};
render() {
// ...
}
}
navigationOptions
で渡されている関数のnavigation
はreact-navigation
のNavigationScreenProps
の型を使います。これは、react-native-router-flux
がreact-navigation
をベースとして拡張しているためです。
RightButton をタップした時に、Component 内部のハンドラを実行する
RightButton をタップした時に、Component 内部のハンドラを実行するにはButton
Component のonPress
を使えば可能です。しかし、static
プロパティ内部から PageComponent 内の private function を呼び出すにはひと工夫必要でした。
static
プロパティ内部から PageComponent の function を実行するには、props のnavigation
を通じて function の参照を渡すことで可能となります。
componentDidMount
の中で props のnavigation.setParam
を使うことで参照を渡すことができます。
// ...
import { NavigationScreenProp, NavigationScreenProps } from "react-navigation";
export interface Props {
navigation: NavigationScreenProp<any, any>;
}
class Page extends React.Component<State, Props> {
static navigationOptions = ({ navigation }: NavigationScreenProps) => {
return {
headerRight: <Button title="+1" />,
};
};
componentDidMount() {
// ここでハンドラの参照をセットする
this.props.navigation.setParams({ onRight: this.onRight });
}
// ...
}
渡されたハンドラの参照を次のようにnavigationOptions
で使うことができます。
// ...
class Page extends React.Component<State, Props> {
static navigationOptions = ({ navigation }: NavigationScreenProps) => {
return {
- headerRight: <Button title="+1" />
+ headerRight: <Button title="+1" onPress={navigation.getParam('onRight')} />
};
}
// ...
これで RightButton をタップした時にonRight
が呼び出されるようになります。
外部からの props の値で RightButton を出し分けする
外部からの props も上の方法と同様にnavigation.setParam
とgetParam
を使って実現します。
今回は props でhasButton
が渡されるとします。componentDidMount
の中で再びnavigation.setParam
を使います。
// ...
componentDidMount() {
// ここでハンドラの参照をセットする
this.props.navigation.setParams({ onRight: this.onRight });
+ this.props.navigation.setParams({ hasButton: this.props.hasButton });
}
// ...
この値をnavigationOptions
の中で使います。
// ...
class Page extends React.Component<State, Props> {
static navigationOptions = ({ navigation }: NavigationScreenProps) => {
return {
- headerRight: <Button title="+1" onPress={navigation.getParam('onRight')} />
+ headerRight: navigation.getParam('hasButton') ?
+ <Button title="+1" onPress={navigation.getParam('onRight')} /> :
+ undefined
};
}
// ...
これで props 経由で RightButton を出し分けすることができるようになりました。
。。。大変。
以上