本文へスキップ
バージョン: 6.x

画面間の移動

前のセクション、「React Navigation入門」では、2つのルート(HomeDetails)を持つスタックナビゲータを定義しましたが、ユーザーがHomeからDetailsに移動する方法については説明しませんでした(コード内で初期ルートを変更する方法については説明しましたが、ユーザーに別の画面を表示するためにリポジトリをクローンしてコード内のルートを変更させることは、想像できる最悪のユーザーエクスペリエンスの1つです)。

これがウェブブラウザであれば、次のような記述ができます。

<a href="details.html">Go to Details</a>

別の書き方としては、次のようなものがあります。

<a
onClick={() => {
window.location.href = 'details.html';
}}
>
Go to Details
</a>

後者と同様の方法を使用しますが、window.locationグローバル変数を使用する代わりに、画面コンポーネントに渡されるnavigationプロップを使用します。

import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}

// ... other code from the previous section

これを詳しく見ていきましょう

  • navigation - navigationプロップは、ネイティブスタックナビゲータ内のすべての画面コンポーネント定義)に渡されます(これについては後ほど「navigationプロップの詳細」で詳しく説明します)。
  • navigate('Details') - ユーザーを移動させたいルートの名前を指定して、navigate関数(navigationプロップ上にある - 名前付けは難しい!)を呼び出します。
注記

ナビゲータで定義していないルート名でnavigation.navigateを呼び出すと、開発ビルドではエラーが、本番ビルドでは何も起こりません。言い換えれば、ナビゲータで定義されているルートにのみ移動できます。任意のコンポーネントに移動することはできません。

したがって、現在2つのルートを持つスタックがあります。1) Homeルート 2) Detailsルート。Details画面からもう一度Detailsルートに移動するとどうなるでしょうか?

function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}

このコードを実行すると、「もう一度Detailsへ移動」をタップしても何も起こらないことに気付くでしょう!これは、すでにDetailsルートにいるためです。navigate関数は、おおよそ「この画面に移動する」という意味であり、すでにその画面にいる場合は、何も起こらないのは理にかなっています。

実際に別の詳細画面を追加したいとしましょう。これは、各ルートに一意のデータを渡す場合によくあります(これについては、後でparamsについて説明する際に詳しく説明します)。これを行うには、navigatepushに変更できます。これにより、既存のナビゲーション履歴に関係なく、新しいルートを追加するという意図を表現できます。

<Button
title="Go to Details... again"
onPress={() => navigation.push('Details')}
/>

pushを呼び出すたびに、新しいルートがナビゲーションスタックに追加されます。navigateを呼び出すと、まずその名前の既存のルートを探し、スタックにまだ存在しない場合にのみ新しいルートをプッシュします。

戻る

ネイティブスタックナビゲータによって提供されるヘッダーには、アクティブな画面から戻る操作が可能である場合(ナビゲーションスタックに画面が1つしかない場合、戻る操作はできないため、戻るボタンはありません)、自動的に戻るボタンが含まれます。

プログラムでこの動作をトリガーしたい場合があり、その場合はnavigation.goBack();を使用できます。

function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.push('Details')}
/>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
注記

Androidでは、React Navigationはハードウェアの戻るボタンにフックし、ユーザーが押すとgoBack()関数を自動的に実行するため、ユーザーの期待どおりに動作します。

もう1つの一般的な要件は、複数画面に戻る操作です。たとえば、スタックで複数の画面深くに入り込み、それらすべてを閉じてもう最初の画面に戻りたい場合です。この場合、Homeに戻りたいことがわかっているので、navigate('Home')pushではありません!試して違いを確認してください)を使用できます。別の方法としては、スタック内の最初の画面に戻るnavigation.popToTop()があります。

function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.push('Details')}
/>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
<Button title="Go back" onPress={() => navigation.goBack()} />
<Button
title="Go back to first screen in stack"
onPress={() => navigation.popToTop()}
/>
</View>
);
}

まとめ

  • navigation.navigate('RouteName')は、スタックにまだない場合、新しいルートをネイティブスタックナビゲータにプッシュします。そうでない場合は、その画面にジャンプします。
  • navigation.push('RouteName')は何度でも呼び出すことができ、ルートをプッシュし続けます。
  • ヘッダーバーには自動的に戻るボタンが表示されますが、navigation.goBack()を呼び出すことでプログラムで戻る操作を行うことができます。Androidでは、ハードウェアの戻るボタンは期待どおりに動作します。
  • navigation.navigate('RouteName')を使用してスタック内の既存の画面に戻ることも、navigation.popToTop()を使用してスタック内の最初の画面に戻ることもできます。
  • navigationプロップは、すべての画面コンポーネント(ルート構成で画面として定義され、React Navigationによってルートとしてレンダリングされるコンポーネント)で使用できます。