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

Как работает mutableStateOf в Jetpack Compose?

1.0 Junior🔥 162 комментариев
#UI и вёрстка#Многопоточность и асинхронность

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

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

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

Как работает mutableStateOf в Jetpack Compose

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

Основная концепция и связь с Snapshot системой

mutableStateOf возвращает объект типа MutableState<T>, который является наблюдаемым (observable) контейнером для значения типа T. Его ключевая особенность — интеграция с Snapshot системой Compose. Эта система отслеживает, какие композируемые функции (composables) "читают" значение State во время выполнения или "снапшота" (snapshot).

Рабочий цикл выглядит так:

  1. Композируемая функция читает значение свойства .value объекта State.
  2. Система Snapshots автоматически регистрирует этот факт, подписывая функцию на изменения данного конкретного State.
  3. Когда значение изменяется (через присваивание state.value = newValue), Snapshot система уведомляет об этом все подписанные композируемые функции, которые были считаны в течение последнего применимого снапшота.
  4. В результате эти функции помечаются как невалидные (invalid) и планируются к повторному выполнению — запускается рекомпозиция.

Практическое использование и механизм сравнения

@Composable
fun Counter() {
    // Создание наблюдаемого состояния. Рекомпозия произойдет при изменении count.value.
    var count by remember { mutableStateOf(0) }
    // Альтернативная запись: val count = remember { mutableStateOf(0) }

    Button(onClick = { count++ }) { // Изменение `.value` запускает рекомпозицию
        Text(text = "Clicked $count times")
    }
}

Важный аспект — механизм определения изменений. mutableStateOf принимает необязательный параметр policy: SnapshotMutationPolicy, который определяет, как сравнивать старое и новое значение. Это напрямую влияет на то, будет ли запущена рекомпозиция.

  • structuralEqualityPolicy() (ПО УМОЛЧАНИЮ): Использует equals() (==). Рекомпозиция произойдет, если новое значение не структурно равно старому.

    var data by remember { mutableStateOf(MyData("A"), policy = structuralEqualityPolicy()) }
    // data = MyData("A") - рекомпозиции НЕ будет (значения равны)
    // data = MyData("B") - рекомпозиция БУДЕТ
    
  • referentialEqualityPolicy(): Использует ===. Рекомпозиция произойдет только если новое значение ссылается на другой объект в памяти.

    val sameList = listOf(1, 2)
    var list by remember { mutableStateOf(sameList, policy = referentialEqualityPolicy()) }
    // list = sameList - рекомпозиции НЕ будет (та же ссылка)
    // list = listOf(1, 2) - рекомпозиция БУДЕТ (новая ссылка)
    
  • neverEqualPolicy(): Рекомпозиция запускается при любом присваивании, даже если новое значение равно старому. Используется редко.

Критически важная деталь: remember

Обычно mutableStateOf используется в паре с remember. Без remember состояние создавалось бы заново при каждой рекомпозиции, сбрасываясь к исходному значению и приводя к потере данных и бесконечным циклам.

// ПРАВИЛЬНО: состояние сохраняется между рекомпозициями.
var state by remember { mutableStateOf(0) }

// ОШИБКА: 'state' будет пересоздан (сброшен в 0) при каждой рекомпозиции.
var state = mutableStateOf(0)

Под капотом: интеграция с Recomposer

Объект MutableState реализует интерфейс StateObject. При чтении его значения во время фазы композиции (composition), система Compose через Snapshot.registerApplyObserver автоматически фиксирует зависимость между текущим RecomposeScope (областью рекомпозиции) и этим состоянием. Когда значение мутирует, все затронутые RecomposeScope помечаются как невалидные. Recomposer, движок рекомпозиции, асинхронно собирает эти невалидные области и запрашивает их повторную композицию в следующем кадре.

Итог: mutableStateOf — это не просто "обертка с коллбэком". Это интеллектуальная часть глубоко интегрированной системы отслеживания зависимостей на уровне снапшотов, которая обеспечивает точную, эффективную и минимально необходимую рекомпозицию только тех частей UI, состояние которых действительно изменилось.

Как работает mutableStateOf в Jetpack Compose? | PrepBro