Composable функции работают не совсем так, как обычные вызовы методов: они могут перезапускаться по множеству раз в зависимости от входных данных или при изменении состояния, поэтому нельзя хранить критичные данные в локальных переменных, а следует оборачивать их в вызов remember:
@Composable
fun CoffeeListScreen() {
val repository = remember {
CoffeeRepository()
}
// ...
}
Функция remember сохраняет вычисляемое лямбдой значение в слот-таблицу для дальнейшего к нему доступа при последующих вызовах Composable функции.
Слот-таблица - некоторый контейнер, используемый для хранения данных Composable дерева: вызов Composable функции создаёт группу в таблице, в пределах таких групп создаются слоты, те самые данные, которые сохраняются при повторном вызове функции в дереве.
В качестве сохраняемого значения remember может быть любой подтип Any? или наследники класса RememberObserver:
remember {
// callback'и для отслеживания жизненного цикла значений в слот-таблице, чтобы реализовать некоторые side effects
object : RememberObserver {
// значение было записано в слот-таблицу, обычно вызывается только 1 раз при первом вызове Composable функции, используется при вызове корутины в LaunchedEffect
override fun onRemembered() {}
// не получилось записать значение в слот-таблицу, возможно какая-то ошибка, используется для отмены корутины в LaunchedEffect
override fun onAbandoned() {}
// значение было удалено из слот-таблицы, так как Composable функции уже нет в дереве, используется для выполнение onDispose действия в DisposableEffect или для отмены корутины в LaunchedEffect
override fun onForgotten() {}
}
}Существует вариант remember(key1, ..., calculation), который повторно вычисляет значение если был изменён один из ключей, как и вычисляемое значение ключи также хранятся в слот-таблице.
Пишите в комментах ваше мнение и всем хорошего кода!
