6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

React Navigationのnavigateとpushは何が違うのか

Posted at

##はじめに
つい最近GraphQLやApollo、ReactNativeを触り始めた初学者です。違う点などあればコメントいただけると嬉しいです!
インターンの業務でnavigation.navigate()navigation.push()は同じ画面遷移に見えるけど何が違うんだ!?と思ったので自分なりにまとめてみます。

##navigateとpushの違いを知って、実装するときに役立てたい
まずはお馴染み(?)の公式ドキュメントで確認してみると、、

navigation

  • navigate - go to another screen, figures out the action it needs to take to do it
  • push - push a new route onto the stack

と言っていますね。この通りの解釈だとnavigateは単なる別の画面への遷移、pushはstack上に新しいrouteが作られるようです。

###routeってなんぞや...
単語の意味の通り、経路みたいなものだと思っています。

以下のコードを見てください。

// In App.js in a new project

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

const Stack = createNativeStackNavigator();

function HomeScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
    </View>
  );
}

function DetailsScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
    </View>
  );
}


function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

このname="Home",name="Details"がroute nameです。(このroute nameは地点名という印象を持つとわかりやすいかなと思います)stack navigatorを作ることで、HomeとDetailsという地点を結ぶ経路ができているイメージです。

###navigateとpushの違い
とてもわかりやすく書かれているなと思ったのが公式のこの部分。
https://reactnavigation.org/docs/navigating/

簡潔に言うと、navigateはすでに存在する画面(route)を行き来し、一方でpushは新しくstack上に画面遷移のrouteを作ると言う点で異なります。

上のコードでHomeScreenにいる状態からDetailsに遷移してみます。この時は上で述べたようにすでにHomeとDetailsを結ぶrouteができているのでnavigation.navigateを使用します。
Home Componentを以下のように修正してボタンを押すことでDetailsに飛んでみましょう。

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>
  );
}

では次にあまり見かけませんがDetailsからDetailsに飛んでみましょう。Detailsを以下のように修正してみます。この時はnavigation.pushを使用します。なぜかというと、HomeとDetails間のrouteはすでに存在していますが、DetailsとDetails間のrouteはまだ作成されていないからです。仮にnavigation.navigateを使用しても画面は遷移されません。

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>
  );
}

こんなイメージです!
navigation.png

###navigation.navigateを使う場面でnavigation.pushを使ってしまうとどうなるのか

単純に画面に遷移するはずが新しく経路を作ってしまいます。

ここからは私個人がこんな問題が起きるんじゃないかな?と予想していることなのですが...

経路を作るたびすなわちnavigation.pushを使うたびにheaderには自動的に一つ前の画面に戻ることができるnabigation.goBack()という機能が提供されます。

push()したときにこのgoBack()を使うとpush()を実行した一つ前の画面に戻ります。上の例では画面が二つしかないのでわかりにくいのですが、画面の数がもっと増えてくると画面を操作して遷移しているうちに意図した画面に戻れなくなる可能性があるのかなと思います。

6
5
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
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?