Using state in Jetpack Composeのcodelabで概念的な用語を拾うメモ

以下で色々概念的な説明があるので拾っていきます。
Using state in Jetpack Compose
https://developer.android.com/codelabs/jetpack-compose-state#0

なんとなくはそれぞれ分かっているんですが、ちょっと一旦用語の整理的な感じなことをしておきます。
だんだん下に行くにつれてレベルアップしていくかも？？

# Stateとは？


> State in an application is any value that can change over time.

> For example it may be a value stored in a Room database, a variable on a class, or even the current value read from an accelerometer.


アプリケーションにおけるStateとは時間とともに変化しうる値。
例えばRoom databaseに保存される値やクラスにある変数。加速度計から読み取った今の値でさえstate。

すべてのAndroidアプリはStateをユーザーに見せている。

# イベントとは？

> Events notify a part of a program that something has happened.

> For example, a user pressing a button will call a click event.

何かが起こったことをプログラムの一部に知らせるもの。
例えばユーザーがボタンをクリックするとクリックイベントが発生する。

# Unstructured state(構造化されていない状態)とは？

from: https://developer.android.com/codelabs/jetpack-compose-state#2

```kotlin
class HelloCodelabActivity : AppCompatActivity() {

   private lateinit var binding: ActivityHelloCodelabBinding
   var name = ""

   override fun onCreate(savedInstanceState: Bundle?) {
       /* ... */
       binding.textInput.doAfterTextChanged {text ->
           name = text.toString()
           updateHello()
       }
   }

   private fun updateHello() {
       binding.helloText.text = "Hello, $name"
   }
}
```

> Code like this does work, and for a small example like this it's fine. However, it tends to become hard to manage as the UI grows.

このようなコードは動作し、このような小さいサンプルコードは大丈夫。しかし、アプリのUIが成長していくにしたがって、管理が難しくなりやすい。

> As you add more events and state to an Activity built like this several problems can arise:

このように作られたActivityにイベントやStateを追加していくと以下のいくつかの問題が発生する。

> Testing – since the state of the UI is interwoven with the Views it can be difficult to test this code.

テスト - このUIのStateがViewと密接に連携しているので、このコードをテストするのが困難。

> Partial state updates – when the screen has many more events, it is easy to forget to update part of the state in response to an event. As a result the user may see an inconsistent or an incorrect UI.

部分的なStateの更新 - もっとたくさんのイベントをこの画面が持ったときに、イベントに対応するStateのアップデートを忘れやすい。結果的にユーザーは一貫性がないか間違ったUIを表示する。

> Partial UI updates – since we're manually updating the UI after each state change, it's very easy to forget this sometimes. As a result the user may see stale data in their UI that randomly updates.

部分的なUIの更新 - 状態の変更後にUIを手動で更新するので、ときどきこれはとても忘れやすい。結果としてランダムに更新された古いデータをUIをユーザーが見ることになる可能性がある。

> Code complexity – it's difficult to extract some of the logic when coding in this pattern. As a result, code has a tendency to become difficult to read and understand.

コードの複雑さ - このパターンでコーディングされた時のロジックの一部を抽出することが困難になる。そのため、コードが読みにくく理解しにくくなる傾向がある。

# Unidirectional Data Flowとは

```kotlin
class HelloCodelabViewModel: ViewModel() {

   // LiveData holds state which is observed by the UI
   // (state flows down from ViewModel)
   private val _name = MutableLiveData("")
   val name: LiveData<String> = _name

   // onNameChanged is an event we're defining that the UI can invoke
   // (events flow up from UI)
   fun onNameChanged(newName: String) {
       _name.value = newName
   }
}

class HelloCodeLabActivityWithViewModel : AppCompatActivity() {
   private val helloViewModel by viewModels<HelloCodelabViewModel>()

   override fun onCreate(savedInstanceState: Bundle?) {
       /* ... */

       binding.textInput.doAfterTextChanged {
           helloViewModel.onNameChanged(it.toString()) 
       }

       helloViewModel.name.observe(this) { name ->
           binding.helloText.text = "Hello, $name"
       }
   }
```

https://developer.android.com/codelabs/jetpack-compose-state#2 より

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/a3b94257-eaa1-84ed-24dd-01b45b76fa3c.png)

> Unidirectional data flow is a design where state flows down and events flow up. By structuring our code this way we gain a few advantages:

Unidirectional data flowはイベントは上に流れ、Stateが下に流れる設計。このようにコードを構成するといくつかのメリットが得られる。

> Testability – by decoupling state from the UI that displays it, it's easier to test both the ViewModel and the Activity

テスト可能性 - 状態を表示するUIから、状態を引き離すことでViewModelとActivityをテストしやすくする。

> State encapsulation – because state can only be updated in one place (the ViewModel), it's less likely that you'll introduce a partial state update bug as your UI grows

Stateのカプセル化 - Stateが一つの場所で更新される(今回のViewModel)ので、UIが成長しても状態更新のバグを起こしにくくなる。

> UI consistency – all state updates are immediately reflected in the UI by the use of observable state holders

UIの一貫性 - 観測可能なState holderを使うことで、すべての状態は瞬時にUIに反映される。

# State hoistingとはなにか？

> State hoisting is a pattern of moving state up to make a component stateless.

State hostingは状態を上に動かしてcomponentをstatelessに変えるパターン。

> When applied to composables, this often means introducing two parameters to the composable.
> value: T – the current value to display
> onValueChange: (T) -> Unit – an event that requests the value to change, where T is the proposed new value

Composableに適応する場合は、2つのパラメータをComposableに追加することをよく意味する。
value: T - 表示する今の値
onValueChange: (T) -> Unit - 値を変更を要求するイベント。ここではTは提案された新しい値。

# Stateful composableとはなにか？

> A stateful composable is a composable that owns a piece of state that it can change over time.

時間とともに変化する可能性があるStateの一部を保持するComposable。

# Recompositionとは何か？

> Recomposition is the process of running the same composables again to update the tree when their data changes

データが変わったときに木をアップデートさせるために同じコンポーザブルをもう一度走らせるプロセス。

# Side effectとは何か？

> A side-effect is any change that's visible outside of a composable function.
> Recomposing a composable should be side-effect free.
> For example, updating state in a ViewModel, calling Random.nextInt(), or writing to a database are all side-effects.

composable関数の外部に見える変更。
Recomposeはside effectがないようにしなくてはいけない。
例えば、ViewModelの状態を変更したり、Random.nextInt()を呼んだり、データベースに書き込むようなもの。

# idempotent composableとはなにか？ (idempotence = 冪等性)

> An idempotent composable always produces the same result for the same inputs and has no side-effects on recomposition.

idempotent composableは常に同じinputに対して同じ結果になり、recomposition時にSide effectがない。

> Composables should be idempotent to support recomposition.

Composable関数はRecompositionに対応するためにidempotentでなければならない。

# Slotsとはなにか

> Slots are parameters to a composable function that allow the caller to describe a section of the screen.

composable関数へのパラメーターで、画面のセクションを呼び出し元で表現できるようにするもの

> Declare a slot with a parameter of type @Composable () -> Unit.

slotは `@Composable () -> Unit` のパラメーターで表される。

# まとめ

理解したと思っていても、読んでみると知らないものが出てきて意外と勉強になります。
次は `A Compose state of mind` を見ていくつもりです。 :eyes: