0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Jetpack Compose】snapshotFlowとdistinctUntilChangedの違いを2分で整理する

Posted at

LaunchedEffectなどでよく使うsnapshotFlow。
見た目がdistinctUntilChanged()と似ていて、「どちらも重複を弾くのでは?」と思ったことはありませんか。

実は似ているようで、扱う世界がまったく異なります。
この記事では、両者の違いと使い分けを簡潔に整理します。

結論:見ている世界が違う

観点 snapshotFlow distinctUntilChanged
対象 ComposeのState Flowの値
判定基準 Stateの再読み取りと等価チェック equals()による同一判定
主な用途 Compose → Flow変換 Flow内の重複除去
  • snapshotFlowは「Composeの再読み取り」をトリガーにFlowをemitします。
  • distinctUntilChangedは「Flowの連続した値が同じならスキップ」します。

前者はComposeの世界、後者はFlowの世界で動作します。

snapshotFlowとは

snapshotFlowは、ComposeのStatederivedStateOfをFlowに変換するAPIです。

snapshotFlow { uiState.value }

Composeの再compose時に、このブロック内で読み取られているStateが変わるとFlowに値をemitします。
内部的にはequals()で比較しているわけではなく、Composeのスナップショットシステムが「Stateに変更があった」と判断したときにemitします。
つまり、snapshotFlowはComposeの状態管理の仕組みに基づいて動作します。

distinctUntilChangedとは

distinctUntilChanged()は、Kotlin Flowの標準演算子です。
Flowの中で、前回とequals()で同じ値が続く場合、その値をスキップします。

flowOf(1, 1, 2, 2, 3)
    .distinctUntilChanged()
// => 1, 2, 3 が流れる

Composeとは無関係に、Flowの中の値の同一性だけを見ています。

両方使うと便利なケース

たとえば、uiState.listがlistOf(...)で毎回新しいインスタンスを返す場合。

snapshotFlow { uiState.list }
    .distinctUntilChanged()

snapshotFlowだけでは、リストが毎回新しい参照になるため、毎回emitされます。
このとき.distinctUntilChanged()を追加すると、中身が同じならスキップされます。

  • snapshotFlowで「Composeの状態変化」を拾う
  • distinctUntilChangedで「値の重複」を防ぐ

この組み合わせは実務でもよく使われます。

まとめ

目的 適したAPI
ComposeのStateをFlowに変換したい snapshotFlow
Flow内の連続した重複値を除きたい distinctUntilChanged
両方やりたい snapshotFlow { … }.distinctUntilChanged()
0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?