React Navigation

画面遷移とパラメータ

画面遷移とパラメータ

Navigatorオブジェクトを使ってReact Navigationの利用画面として定義した画面(Screenのcomponentプロパティで指定したコンポーネント)は描画される際にnavigationというプロパティが設定されます。このnavigationプロパティ(オブジェクト)を利用することにより、「Detail画面へ遷移する」のような処理を記述することができます。

class HomeScreen extends React.Component {
render() { // propsからnavigationオブジェクトを取り出し
const { navigation } = this.props;
return (
<View style={styles.container}>
<Text>Home</Text>
<View style={{marginVertical: 10}}>
<Button
title="Push" // navigateメソッドを使うことで指定した画面に遷移できる
onPress={() => navigation.navigate('Detail')}
/>
</View>
</View>
);
}
}

一覧画面で要素をタップして詳細画面を表示するような場合、詳細画面に「どれを表示するのか」という情報を渡す必要があります。これにはnavigateメソッドの第2引数を使用します。パラメータとして任意のオブジェクト(アプリで利用するために必要な情報)を渡すことができます。

        <View style={{marginVertical: 10}}>
<Button
title="Param 1" // idが1のデータを表示するように指示
onPress={() => navigation.navigate('Detail', {id: 1})}
/>
</View>
<View style={{marginVertical: 10}}>
<Button
title="Param 2"
// idが2のデータを表示するように指示
onPress={() => navigation.navigate('Detail', {id: 2})}
/>
</View>

遷移先の画面ではrouteプロパティのparamsを参照することで渡されたパラメータ(オブジェクト)を受け取ることができます。

class DetailScreen extends React.Component {
render() { // propsからrouteオブジェクトを取り出し
const { route } = this.props; // さらに渡されたオブジェクトから必要なプロパティを取り出し
const { id } = route.params;
return (
<View style={styles.container}>
<Text>Detail</Text>
<Text>ID is {id}</Text>
</View>
);
}
}
画面外からnavigationオブジェクトにアクセスする

React Navigationが管理する画面の外部からnavigationオブジェクトにアクセスするには、NavigationContainerにrefプロパティを設定し、navigationオブジェクトの参照を取得します。なお、起動直後はrefプロパティで指定した関数がまだ実行されておらず、navigationRefがundefinedの可能性があるため、if文で囲むなどメソッドを呼び出す際には注意が必要です。

      <NavigationContainer
        // stateではなく通常のオブジェクトプロパティとして設定します
ref={ref => this.navigationRef = ref}
>
ネストされている画面への遷移

Tab Navigator内にStack Navigatorを表示しているなどのネストされた画面ではネストされている状態に沿って画面遷移を指定する必要があります。これは次のコード例のようにnavigateメソッドの第2引数のオブジェクトでscreenプロパティを指定します。この方法は以下のURLで説明されています。
https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator

  showPhotoEdit(id) {
fetchOnePhoto(id)
.then(photo => { // 起動直後はnavigationRefがundefinedの可能性があるためif文で囲む必要がある
if (this.navigationRef) { /* 第2引数のオブジェクトはProfile画面に渡すパラメータではなく Profile(タブ)中のどの画面を表示するかを指定する */
this.navigationRef.navigate('Profile', { // Profile中で表示したい画面
screen: 'PhotoEdit', // PhotoEditを初期画面としない(戻る矢印をタップするとユーザー画面に戻るようにする)
initial: false, // PhotoEdit画面に渡すパラメータはparamsプロパティで指定する
params: { photo }
});
}
});
}