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

Что такое mutable состояние в Jetpack Compose?

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

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

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

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

Что такое mutable состояние в Jetpack Compose?

В Jetpack Compose, mutable состояние (или изменяемое состояние) — это центральная концепция, которая представляет данные, которые могут меняться во времени и должны вызывать рекомпозицию (recomposition) части UI при их изменении. Compose — это декларативный фреймворк, где UI описывается как функция состояния. Когда состояние меняется, фреймворк автоматически перерисовывает (рекомпонует) соответствующие части интерфейса.

Ключевые принципы состояния в Compose

Состояние в Compose должно быть наблюдаемым (observable). Это означает, что система Compose должна отслеживать изменения в этих данных, чтобы знать, когда нужно запустить рекомпозицию. Простое использование обычной переменной (var) внутри функции @Composable не работает, потому что Compose не сможет автоматически отслеживать её изменения.

Основные инструменты для mutable состояния

Для создания и управления mutable состоянием Compose предоставляет несколько API:

1. mutableStateOf

Это фундаментальная функция, которая создает объект MutableState<T>, являющийся наблюдаемым контейнером для значения. Compose отслеживает чтения (read) этого объекта во время рекомпозиции и планирует повторную рекомпозицию при его изменении (write).

import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun Counter() {
    // Создание и 'запоминание' mutable состояния
    val count = remember { mutableStateOf(0) }

    Button(onClick = { count.value++ }) {
        Text("Clicked ${count.value} times")
    }
}

Здесь count.value — это mutable состояние. При каждом клике значение изменяется, и Compose рекомпонует Text, чтобы отобразить новое число.

2. remember

Функция remember используется для сохранения объекта в памяти во время рекомпозиции. Без remember состояние создавалось бы каждый раз при рекомпозиции, теряя свои изменения. remember хранит состояние только в пределах одной композиции (вызова Composable функции).

3. rememberSaveable

Аналог remember, но сохраняет состояние через процесс смерти активности (например, при повороте устройства или выходе из приложения). Использует механизмы Bundle или SaveableStateRegistry.

val savedCount = rememberSaveable { mutableStateOf(0) }

Расширения для делегирования свойств

Для более удобного синтаксиса Compose предоставляет делегированные свойства:

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun DelegatedPropertyExample() {
    var count by remember { mutableStateOf(0) }

    Button(onClick = { count++ }) { // Прямое изменение без .value
        Text("Count: $count")
    }
}

Ключевое слово by позволяет использовать count как обычную переменную, но на самом деле изменения отслеживаются через делегат MutableState.

State Hoisting (Поднятие состояния)

Часто состояние не хранится внутри Composable функции, а поднимается (hoisted) на более высокий уровень — в родительскую функцию или даже в ViewModel или State Holder. Это делает компоненты более переиспользуемыми и тестируемыми, отделяя логику состояния от UI-рендеринга.

@Composable
fun StatefulCounter() {
    var count by remember { mutableStateOf(0) }
    StatelessCounter(count = count, onCountIncrease = { count++ })
}

@Composable
fun StatelessCounter(count: Int, onCountIncrease: () -> Unit) {
    Button(onClick = onCountIncrease) {
        Text("Count: $count")
    }
}

Здесь StatelessCounter — это stateless компонент, который получает состояние и события извне.

Управление сложным состоянием

Для более сложных объектов состояний, содержащих несколько полей, используются:

  • mutableStateListOf для наблюдаемых списков.
  • mutableStateMapOf для наблюдаемых карт (map).
  • Классы данных (data class) вместе с mutableStateOf.
data class UserState(val name: String, val age: Int)

@Composable
fun UserProfile() {
    var userState by remember {
        mutableStateOf(UserState("Alice", 25))
    }
    // Изменение: userState = userState.copy(age = 26)
}

Связь с архитектурой

Mutable состояние в Compose часто является "представителем" (proxy) для состояния из архитектурных слоев, таких как:

  • ViewModel, где состояние может быть LiveData, StateFlow или Observable State. StateFlow особенно популярен, его можно наблюдать в Compose через collectAsState().
import androidx.lifecycle.viewmodel.compose.viewModel

@Composable
fun FlowExample(viewModel: MyViewModel = viewModel()) {
    val uiState by viewModel.uiState.collectAsState()

    Text(text = uiState.message)
}

Заключение

Mutable состояние в Jetpack Compose — это наблюдаемые данные, которые при изменении автоматически запускают рекомпозицию соответствующих @Composable функций. Правильное использование mutableStateOf, remember и принципов поднятия состояния (state hoisting) является ключом к созданию реактивных, эффективных и поддерживаемых UI в современном Android развитии. Оно связывает декларативный UI с изменяющимися данными, обеспечивая принцип "UI как функция состояния".