0
1

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.

Jetpack ComposeのNavigationを使うと遷移先の画面が繰り返し表示される問題

Last updated at Posted at 2022-06-03

こんにちは。
最近は宣言的UIが流行っていますね。
Flutterでよく書いていてもう見慣れたのですが、初めて見たときはネストの量にギョッとした記憶があります。
最近はJetpack Composeに挑戦中です。
そんな中でログイン機能を実装していてどハマりしたので共有したいなと思い今回の記事を書くに至りました。

まず状況として、「ログインしていない場合は上からログイン画面を被せる」という仕様を満たそうとした時に、ログイン画面が繰り返し表示されてしまう不具合にハマりました。

これが起きてしまった原因は、結論から言いますと、「Composable内で画面遷移をしようとしたから」です。
具体的にどんなコードを書いていたかというと、

HomeScreen.kt
@Composable
fun HomeScreen(
    viewModel: HomeViewModel,
    navController: NavController
) {
    val uiState by produceState(
        initialValue = HomeUiState(isLoading = true)
    ) {
        val currentUser = viewModel.currentUser()
        value = HomeUiState(isLoading = false, currentUser = currentUser)
    }

    if (!uiState.isLoading && uiState.currentUser == null) {
        navController.navigate(ScreenRoutes.login)
    }

こんな感じで、currentUserがnullのとき(ログインしていないとき)はログイン画面に遷移するというコードを書いていました。
Composable内でnavigate()をしているのがまずかったようです。

全然原因がわからずブレークポイントを貼ったり公式ドキュメントをあちこち読んで途方に暮れていました。
が、よく見たら・・・

You should only call navigate() as part of a callback and not as part of your composable itself, to avoid calling navigate() on every recomposition.

めちゃくちゃ書いてた・・・
Composableの一部としてnavigate()を呼ぶな、と公式ドキュメントにめちゃくちゃ書いてました・・・

とても辛い気持ちになりましたが、これが原因でした。

ちなみに解決策としては

    if (!uiState.isLoading && uiState.currentUser == null) {
        LaunchedEffect(Unit) {
            navController.navigate(ScreenRoutes.login)
        }
    }

これでオッケーでした。

Jetpack Compose自体がまだまだ出来立てだから不具合が多いのかなと思っていましたが、想像以上に自分の知識不足だったパターンが多いです。
ちゃんと勉強しなきゃですね・・・

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?