Функция SideEffect
Функция SideEffect вызывает лямбду
на каждой успешной перерисовке,
когда composable уже в дереве.
Это не suspend и не даёт onDispose.
Подходит для синхронной синхронизации
с объектом вне Compose, например
обновить поле у ViewModel без Flow.
Для подписок с отменой лучше
DisposableEffect
или LaunchedEffect.
Синтаксис
SideEffect {
external.value = state.value
}
Параметры
| Параметр | Описание |
|---|---|
effect |
Лямбда без аргументов. Выполняется после commit перерисовки. |
Пример
Давайте запишем текст состояния во внешнюю переменную:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.SideEffect
class MainActivity : ComponentActivity() {
private var lastText = "abcde"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var text by remember { mutableStateOf("abcde") }
SideEffect {
lastText = text
}
Button(onClick = {
text = if (text == "abcde") "12345" else "abcde"
}) {
Text(text = "abcde")
}
Text(text = text)
}
}
}
На экране текст на кнопке меняется, а поле lastText в активности повторяет его после каждой перерисовки.
Пример
Давайте увеличим счётчик side-эффектов при смене текста:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.SideEffect
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var text by remember { mutableStateOf("abcde") }
var ticks by remember { mutableIntStateOf(0) }
SideEffect {
ticks++
}
Button(onClick = {
text = if (text == "abcde") "12345" else "abcde"
}) {
Text(text = "abcde")
}
Text(text = if (ticks < 2) "abcde" else "12345")
}
}
}
На экране после нескольких перерисовок
нижний текст станет "12345".
Смотрите также
-
функция
DisposableEffect,
которая снимает эффект через onDispose -
функция
LaunchedEffect,
которая запускает корутину -
функция
mutableStateOf,
которое читают в SideEffect -
класс
ViewModel,
поля которого иногда синхронизируют так