Jetpack Composeを効果的に使うためには、Composableの親子構造とデータフローの考え方を理解する必要があります。
この記事では、基本的な考え方と実装方法について解説します!
基本的な親子構造とデータフロー
Jetpack Composeでは、UIコンポーネント(Composable)が階層的に組み合わされて構築されます。その際、親から子へデータを一方向に渡し、子Composableで発生したイベントは親にコールバックとして返すのが基本パターンです。
- 親Composable は状態(State)を保持して子にデータを渡す
- 子Composable は受け取ったデータを使ってUIを表示する
- 子で発生したイベントはコールバック関数を通じて親に通知し、親がデータを更新する
データの流れを一方向にすることで、状態管理が明確になり、予測可能な動作を実現できます。
実装例
簡単な例で、具体的な流れを見てみましょう。
@Composable
fun ParentComposable() {
var message by remember { mutableStateOf("Hello") }
ChildComposable(
message = message,
onMessageChange = { newMessage ->
message = newMessage
},
)
}
@Composable
fun ChildComposable(
message: String,
onMessageChange: (String) -> Unit,
) {
Column {
Text(text = message)
TextField(
value = message,
onValueChange = onMessageChange,
)
)
}
データの一方向フローとState Hoisting
Composeでは、親Composableで状態を管理し、子Composableはその状態を表示するだけに留めるという設計が推奨されています。これをState Hoisting(状態の巻き上げ)と呼びます。
State Hoistingの利点は以下の通りです。
- 状態が一箇所で管理され、デバッグやテストが容易になる
- 子Composableが再利用しやすくなる
- データがどこで変更されたかを把握しやすく、デバッグやメンテナンスが容易になる
子から親へイベントを伝えるコールバック
子Composableでユーザーの操作(ボタンタップやテキスト入力など)を受け取った場合、親にそのイベントを通知するには、イベント用のコールバックをパラメータとして渡します。
例)ボタンタップの通知
@Composable
fun ParentComposable() {
var count by remember { mutableStateOf(0) }
ChildButtonComposable(
onButtonClick = {
count += 1
},
)
}
@Composable
fun ChildComposable(onButtonClick: () -> Unit) {
Button(onClick = onButtonClick) {
Text("Click me!")
}
}
イベントを親に戻すことで、状態を一箇所に集中管理でき、データフローがシンプルになります。
まとめ
- 親Composableがデータや状態を保持し、子Composableへ渡す
- 子Composableはイベントを親にコールバックで通知
- 状態はできる限り親で保持する(State Hoisting)
この基本原則を守ることで、明確でメンテナンス性の高いComposeアプリケーションが構築できます!