派生Stateである DerivedState
を作成する derivedStateOf
の使い所についてです。
基本的な使い方
rememberの中で derivedStateOf
を使います。その中で State
を読み込みます。
これにより、 Stateの counter1
が変化した時にだけ計算が行われます。
var counter1 by remember { mutableStateOf(0) } val counter1MoreThan1 by remember { derivedStateOf { counter1 >= 1 } }
動作確認
counter2を用意しました。 counter1をニ回増やした後に、counter2をニ回増やします。
@Composable private fun Content() { Column { var counter1 by remember { mutableStateOf(0) } var counter2 by remember { mutableStateOf(0) } val counter1MoreThan1 by remember { derivedStateOf { println("call derivedStateOf") counter1 >= 1 } } LaunchedEffect(Unit) { delay(1000) counter1++ delay(1000) counter1++ delay(1000) counter2++ delay(1000) counter2++ } Spacer(modifier = Modifier.width(12.dp)) Text("counter1=$counter1, counter2=$counter2") Text("counter1 more than 1 = $counter1MoreThan1") } }
counter2が増えたときには呼ばれていない事がわかります。
call derivedStateOf before call cunter1++ call derivedStateOf before call cunter1++ call derivedStateOf before call counter2++ before call counter2++
これは、 derivedStateOf
のLambdaの中で、どのStateObjectを読み込んでいるか保存して、変更された事を検知し、変更された時だけ再計算を行うことで実現しています。
https://matsudamper.hatenablog.com/entry/2022/06/28/154855
remember(key)
の使い方
derivedStateOf
は派生Stateであるので、変更はStateObjectしか検知してくれません。
引数が変更された時だけ実行したいだけの場合は remember(key)
を使います。キーが変更された時にだけ中が実行されます。
@Composable private fun Content(uiState: UiState) { Column { val moreThan1 = remember(uiState) { uiState.counter >= 1 } Text("counter1 more than 1 = $moreThan1") } }
ここではcounterしか読み込んでいないので、実際はcounterだけをkeyにすると更に良いです。
@Composable private fun Content(uiState: UiState) { Column { val moreThan1 = remember(uiState.counter) { uiState.counter >= 1 } Text("counter1 more than 1 = $moreThan1") } }