【18:48追記】
今日は天下一品で1,098円のチャーハンセットを食べた。
【追記終わり】
今回の記事は、日記というよりも Jetpack Compose まとめ。
Jetpack Compose は、React を使うフロントエンド開発者が手軽に Android ネイティブアプリ開発者へと移行できるフレームワーク。1ヶ月ほど前に安定版になったため、これからは Jetpack Compose を使ったプロジェクトも増えていくと思う。
React と Jetpack Compose の比較
参考サイト : React to Jetpack Compose RC Dictionary
非同期な useEffect > LaunchedEffect
useEffect
のコールバック関数は非同期関数に出来ないため、非同期な処理を行う場合はコールバック関数内で非同期関数を即時実行する処理を書く必要がある。
更に、処理中の非同期処理はフックの依存配列が変更されたときにキャンセルしなければならないため、キャンセルの処理も書く必要がある。
つまり次のようなコードになる。
useEffect(() => { let unmounted = false; (async () => { const user = await getUser(id); if (unmounted) { return; } setUser(user); })(); return () => { unmounted = true; }; }, [id]);
Jetpack Compose では次の3行で済む。前回の非同期処理はキャンセルされる。
LaunchedEffect(id) { user.value = getUser(id).await() }
注意点として、LaunchedEffect
には必ずキーを渡さなければならない。つまり、React の useEffect(() => { ... }, [])
みたいに LaunchedEffect {}
と書くことはできない。代わりに LaunchedEffect(Unit) {}
と書く。
useState と useEffect > produceState
先程の Kotlin コードを user
の定義も含めて書くと次のようになる。
val user = remember { mutableStateOf<User?>(null) } LaunchedEffect(id) { user.value = getUser(id).await() }
これは、produceState
を使えばもう少し簡潔に書ける。
val user = produceState<User?>(null, id) { value = getUser(id).await() }
value
はどこから来たんだろう?という気持ちになる。
JSX 内の map > for
Jetpack Compose では、React の JSX にあたる部分に for を書くことができる。
val counts = arrayOf(1, 2, 3) for (count in counts) { Text(count.toString()) // コンポーネント }
JSX では必然的に関数型っぽく書く必要があった。
その制限が Jetpack Compose にはない。
key 属性 > key 関数
React では最適化のために key 属性が使われる。
users.map(user => ( <UserInfo key={user.id} user={user} /> ))
Jetpack Compose では key 関数を使って次のように書く。
for (user in users) { key(user.id) { Text(user.name) } }
コンポーネントとフック > @Composable
な関数
React ではコンポーネントとフックは別物だが、Jetpack Compose ではひとつの関数に両方の機能を持たせられる。つまり次のように書ける。
@Composable fun hookAndComponent(): State<Int> { val count = remember { mutableStateOf<Int>(0) } Text("hello, world") return count }
@Component
ではなく @Composable
な理由はここにあると思う。@Composable
な関数はコンポーネントとしてもフックとしても扱える。参考サイトでは key
関数のことを「key Composable」と呼ばれている。これにならって、上記の hookAndComponent()
は hookAndComponent コンポーザブルと呼ぶと良さそう。
おわりに
次は GlobalScope について勉強しようと思う