← Назад к вопросам

В чем разница между remember и rememberSavable в Jetpack Compose?

2.0 Middle🔥 161 комментариев
#Kotlin основы#UI и вёрстка#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между remember и rememberSavable в Jetpack Compose

Основное отличие заключается в области сохранения состояния и поведении при конфигурационных изменениях (например, поворот устройства) или процессной смерти (например, при переходе в фоновый режим). remember сохраняет состояние только в пределах текущей композиции (жизненного цикла Composable), а rememberSavable расширяет это сохранение, добавляя механизм сохранения через SaveableStateRegistry, что позволяет данным "пережить" конфигурационные изменения.

Ключевые характеристики remember

  • Локальное сохранение состояния: Значение, сохраненное с помощью remember, существует только во время текущей жизни Composable. При повторной композиции (например, из-за изменения другого состояния) значение будет сохранено и использовано повторно.
  • Не устойчиво к конфигурационным изменениям: При повороте устройства, изменении языка или других системных событиях, вызывающих recreate Activity/Fragment, все состояние, сохраненное через remember, будет потеряно. Композиция будет полностью перестроена с начальными значениями.
  • Простой API: Используется для хранения объектов, которые не требуют сложной сериализации, например, mutableStateOf.
@Composable
fun CounterWithRemember() {
    // Этот счетчик будет потерян при повороте устройства
    val count = remember { mutableStateOf(0) }

    Button(onClick = { count.value++ }) {
        Text("Count: ${count.value}")
    }
}

Ключевые характеристики rememberSavable

  • Устойчивость к конфигурационным изменениям: Главная задача — сохранить состояние при событиях, которые вызывают recreate UI-контроллера (Activity, Fragment). Это достигается через интеграцию с системным механизмом сохранения состояния (SaveableStateRegistry).
  • Сериализация данных: Для сохранения сложных объектов rememberSavable использует механизм Saver. По умолчанию он может автоматически сохранять типы, поддерживаемые Bundle (например, Int, String, List). Для сложных классов необходимо предоставить кастомный Saver.
  • Расширенная версия remember: По сути, rememberSavable — это remember с дополнительной логикой сохранения/восстановления.
@Composable
fun CounterWithRememberSavable() {
    // Этот счетчик сохранится после поворота устройства
    val count = rememberSavable { mutableStateOf(0) }

    Button(onClick = { count.value++ }) {
        Text("Count: ${count.value}")
    }
}

Когда использовать?

  • remember:
    *   Для UI-состояния, которое является временным и не должно сохраняться (например, состояние раскрытия/скрытия элемента).
    *   Для вычисленных или производных значений, которые зависят от других изменяемых состояний (`derivedStateOf`).
    *   Для хранения ссылок на объекты, которые не являются `Saveable` и сериализация которых невозможна или нежелательна.

  • rememberSavable:
    *   Для **персистентного UI-состояния**, которое должно сохраняться между конфигурационными изменениями (например, текст в поле ввода, выбранная позиция в списке, прогресс в форме).
    *   Когда состояние напрямую связано с **данными пользователя** и его потеря негативно влияет на UX.
    *   В сценариях, где требуется восстановление сложного состояния после процессной смерти (в сочетании с другими механизмами, например, сохранением в `ViewModel`).

Пример с кастомным Saver

Если ваш объект не поддерживается автоматически, нужно реализовать интерфейс Saver.

data class UserSettings(val theme: String, val fontSize: Int)

// Создаем кастомный Saver для сложного объекта
val UserSettingsSaver = Saver<UserSettings, Bundle>(
    save = { settings ->
        Bundle().apply {
            putString("theme", settings.theme)
            putInt("fontSize", settings.fontSize)
        }
    },
    restore = { bundle ->
        UserSettings(
            theme = bundle.getString("theme") ?: "Light",
            fontSize = bundle.getInt("fontSize")
        )
    }
)

@Composable
fun SettingsScreen() {
    // Используем rememberSavable с кастомным Saver
    val settings = rememberSavable(saver = UserSettingsSaver) {
        mutableStateOf(UserSettings("Light", 16))
    }

    // UI для изменения настроек...
}

Итог

Выбор между remember и rememberSavable определяется требованием к персистентности состояния. remember — ваш стандартный инструмент для управления состоянием внутри одной сессии композиции. rememberSavable — это его усиленная версия, которая добавляет устойчивость к системным событиям, разрушающим UI-контроллер, обеспечивая непрерывность пользовательского интерфейса. В современных приложениях для критически важного состояния часто используют гибридный подход: rememberSavable для немедленного восстановления UI, а долгосрочное сохранение реализуют через ViewModel и постоянное хранилище (DataStore, Room).