Upgrade to Pro — share decks privately, control downloads, hide ads and more …

rememberUpdatedState の使いどころを考える

akkie76
November 12, 2023

rememberUpdatedState の使いどころを考える

「potatotips #85 iOS/Android開発Tips共有会」で発表したスライドになります。
https://potatotips.connpass.com/event/299247/

akkie76

November 12, 2023
Tweet

More Decks by akkie76

Other Decks in Technology

Transcript

  1. ©2023 RAKUS Co., Ltd.
    rememberUpdatedState
    の使いどころを考える
    potatotips #85 iOS/Android開発Tips共有会
    2023/11/14
    @akkiee76

    View full-size slide

  2. 自己紹介
    ● Akihiko Sato
    ● Rakus Inc.
    ● 楽楽精算
    ● @akkiee76 / X

    View full-size slide

  3. rememberUpdatedState とは?

    View full-size slide

  4. Compose における Side effect APIs の1つ

    View full-size slide

  5. Compose 可能な関数の範囲外で発生するアプリの状態の変化
    ● 予想しない再コンポジション
    ● 異なる順序でのコンポーザブルの再コンポジション
    ● 破棄可能な再コンポジション
    Compose における Side effect(副作用)とは?
    コンポーザブルは Side effect がないようにするのが理想的
    https://developer.android.com/jetpack/compose/side-effects

    View full-size slide

  6. ● スナックバーを表示する
    ● 1 回限りのイベントをトリガーする
    ● 特定の状態で別の画面に遷移する
    Side effect が必要なケース
    https://developer.android.com/jetpack/compose/side-effects
    予測可能な方法で Side effect を実行する必要がある

    View full-size slide

  7. rememberUpdatedState API とは?
    値が変化しても再起動すべきでない作用を
    参照することができる Side effect API
    https://developer.android.com/jetpack/compose/side-effects?hl=jp#rememberupdatedstate
    再起動が高コストである作用にアプローチができる

    View full-size slide

  8. 最新の時刻を Snackbar に表示するユースケース
    1. remember を利用した場合
    2. LaunchedEffect のキーを更新した場合
    3. rememberUpdatedState API を利用した場合

    View full-size slide

  9. 1. remember を利用した場合

    View full-size slide

  10. var currentTime by remember { mutableStateOf(Date().time.toString()) }
    Button(
    onClick = {
    currentTime = Date().time.toString()
    }
    ) {
    Text(currentTime)
    }
    SnackbarScreen (
    currentTime = currentTime,
    snackbarHostState = snackbarHostState
    )
    時刻を保持
    時刻を更新
    時刻を渡す

    View full-size slide

  11. @Composable
    fun SnackbarScreen(
    currentTime: String,
    snackbarHostState: SnackbarHostState
    ) {
    LaunchedEffect(Unit) {
    delay(3000)
    snackbarHostState.showSnackbar(message = currentTime)
    }
    }
    一度だけ実行

    View full-size slide

  12. 2. LaunchedEffect の key を更新した場合

    View full-size slide

  13. @Composable
    fun SnackbarScreen(
    currentTime: String,
    snackbarHostState: SnackbarHostState
    ) {
    LaunchedEffect(currentTime) {
    delay(3000)
    snackbarHostState.showSnackbar(message = currentTime)
    }
    }
    何も表示されない
    LaunchedEffect が再起動し Coroutine がキャンセル
    currentTimeが更新され続ける

    View full-size slide

  14. 3. rememberUpdatedState API を利用した場合

    View full-size slide

  15. @Composable
    fun SnackbarScreen (
    currentTime: String,
    snackbarHostState : SnackbarHostState
    ) {
    val rememberTime by rememberUpdatedState (newValue = currentTime)
    LaunchedEffect (Unit) {
    delay(3000)
    snackbarHostState .showSnackbar( message = rememberTime)
    }
    }
    最新の値が表示
    値が変化しても LaunchedEffect の Coroutine はキャンセルされない
    currentTimeが更新され続ける

    View full-size slide

  16. @Composable
    fun rememberUpdatedState(newValue: T): State = remember {
    mutableStateOf(newValue)
    }.apply { value = newValue }
    オブジェクトをキャプチャーし、中身を更新している

    View full-size slide

  17. まとめ
    rememberUpdatedState API の使いどころ
    ● Coroutine の処理をキャンセルさせたくないケース
    ○ 重い通信処理(ファイルダウンロード)など
    ● コールバックを利用するケース
    ○ エラーハンドリングなど
    ● 異なる Composable などで変更される値を参照するケース

    View full-size slide

  18. Thank you 🎉

    View full-size slide