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で onChange = { ... } をやめて onChange = ::updateModel に落ち着いた理由

Posted at

はじめに

Jetpack Composeでフォーム系UIを書くと、
ほぼ確実に次のようなコードを書きます。

onChange = { value ->
    updateModel(value)
}

自分も最初は何も疑っていませんでした。

きっかけ

Edit系画面で次のような実装をしていました。


EditBasicForm(
    value = state.model,
    onChange = { m ->
        state = state.copy(model = m.update())
    }
)

見た目は問題なさそうですが、buildが不安定になりました。

起きていた問題

Type mismatch

None of the following candidates is applicable

修正すると別の場所が壊れる

lambdaを少し触るだけで、症状が変わる状態でした。

解決策:lambdaをやめる


EditBasicForm(
    value = state.model,
    onChange = ::updateModel
)

ViewModel側は次の形にしました。


private fun updateModel(m: Model) {
    state = state.copy(
        model = m.update(),
        error = null
    )
}

これで build は安定しました。

なぜこれで解決したのか

lambdaはその場で型推論される

Compose + State + Generics で推論が複雑になる

関数参照はシグネチャが確定している

結果として、型エラーが消えました。

副次的なメリット

ViewModelの責務が明確

UI側が値を渡すだけになる

ロジックが一箇所に集約される

やらなくなったこと

UI側で state.copy を直接書く

lambda内でロジックを書く

「とりあえずlambda」で逃げる

おわりに

lambdaが悪いわけではありません。
ただ、ComposeとState管理が絡む場合は
型を確定させる書き方の方が安全でした。

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?