📱

React Navigation(v6) の Stack(画面遷移履歴)をリセットする方法 | React Native

2021/12/02に公開

本記事の内容

アプリを開発していると、(主に戻るボタンなどによって)スクリーンを戻せないようにしたい場合があります。
そこで今回は、React Navigation v6においてNavigation stackをリセットしたくなった時にどうすれば良いかを紹介します。

サンプルコード

こちらに上げています。
試す場合は以下のコマンドを順に実行してみて下さい。

  1. git clone -b react-navigation-stack-reset https://github.com/naoyahieda/react_native_samples.git
  2. cd react_native_samples
  3. yarn install
  4. yarn start --tunnel

バージョン

"react-native": "0.64.3",
"expo": "~43.0.2",
"@react-navigation/bottom-tabs": "^6.0.9",
"@react-navigation/native": "^6.0.6",
"@react-navigation/native-stack": "^6.2.5",
"@react-navigation/stack": "^6.0.11",

やりたいこと

下の図、写真のようなタブ1,タブ2の2つがある際に、
○ タブ1
--→ FeedScreenOfFirstTab (タブ2から戻った時ここを表示)
--→ NotificationScreenOfFirstTab (ここから)
○ タブ2
--→ FeedScreenOfSecondTab (ここに遷移し、タブ1に戻る)
--→ NotificationScreenOfSecondTab

タブ1のNotificationScreenOfFirstTabからタブ2のFeedScreenOfSecondTabに遷移し、再びタブ1に戻った時に、タブ1でのスクリーン閲覧履歴を消去(=Navigation stackを消去)する。今回は、タブ1に戻った時にFeedScreenOfFirstTabを出すことにする。

Navigation Stackをリセットする方法

基本的には公式ドキュメントを参考にしていけば良いです。
今回は、タブ1におけるNavigation stackをリセットし、次にタブ1に戻った時にFeedScreenOfFirstという名前のスクリーンを出したいので、以下のようなコードを書けば良いです。

CommonActionsのインポート

import { CommonActions } from '@react-navigation/native'

(→ Github)

Stackのリセット& Navigation stateの書き換え

const resetAction = CommonActions.reset({
    index: 1,
    routes: [
        { name: 'FeedScreenOfFirstTab' }
    ]
})

(→ Github)

navigation.dispatch(resetAction)

(→ Github)

これは何を行なっているかというと、CommonActions.resetに所望のNavigation stateを渡し、navigation.dispatchでそれを実行 (=Navigation stackのリセット&所望のNavigation stateに書き換え) しています。

Navigation stateとは、詳しくはこちらを参考にしてもらえると良いのですが、ざっくり言うと現在のNavigatorの状態です。例えば、現在までに見てきたスクリーンの履歴などが入っています。今回はこれをリセットし、書き換えているのです。

リセットの有効範囲

今回試した範囲では、リセットを行なったタブ内のNavigation stackのみをリセットしていて、その他のタブに影響は及んでいませんでした。(Navigation stackの積まれ方に関しては要勉強)

まとめ

Navigation stackをリセット&書き換えする場合は、CommonActions.reset({ 所望のnavigation state })でリセット&書き換え関数を定義し、navigation.dispatchに渡して実行しましょう!

おまけ

現役東大生の家庭教師がかんたんに見つかる個人契約アプリカテアプリ東大生ぜひインストールしてみてください!
また、UIUXでアドバイスなどあればぜひお願いします!

Discussion