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

Как сделать изменяемый стейт в Composable функции

1.0 Junior🔥 161 комментариев
#Android компоненты#UI и вёрстка

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

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

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

Управление изменяемым состоянием в Jetpack Compose

В Jetpack Comppose для создания изменяемого состояния внутри Composable-функций используются специальные API, которые обеспечивают реактивное обновление UI при изменении данных. Вот основные подходы:

1. mutableStateOf() - базовый строительный блок

Функция mutableStateOf() создает объект MutableState, который уведомляет Compose о необходимости рекомпозиции при изменении значения.

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

@Composable
fun CounterExample() {
    // Сохраняем состояние между рекомпозициями
    val count = remember { mutableStateOf(0) }
    
    Button(onClick = { count.value++ }) {
        Text(text = "Кликов: ${count.value}")
    }
}

2. Различные формы объявления состояния

Compose предлагает несколько способов работы с состоянием:

// Способ 1: Явное объявление MutableState
val countState = remember { mutableStateOf(0) }
val count = countState.value

// Способ 2: Деструктуризация (рекомендуется)
var count by remember { mutableStateOf(0) }

// Способ 3: Функция-обертка
val (count, setCount) = remember { mutableStateOf(0) }

3. remember - ключ к сохранению состояния

Функция remember сохраняет значение при рекомпозиции, но сбрасывает при удалении композиции из дерева:

@Composable
fun RememberExample(key: String) {
    // Состояние будет сохранено только для конкретного key
    var text by remember(key) { mutableStateOf("") }
    
    TextField(
        value = text,
        onValueChange = { text = it }
    )
}

4. ViewModel + mutableState для сложной логики

Для бизнес-логики и сохранения состояния при конфигурационных изменениях используйте ViewModel:

class UserViewModel : ViewModel() {
    // StateFlow или LiveData также подойдут
    var userName by mutableStateOf("")
        private set
    
    fun updateName(newName: String) {
        userName = newName
    }
}

@Composable
fun UserProfile(viewModel: UserViewModel = viewModel()) {
    // Состояние автоматически наблюдается из ViewModel
    val userName = viewModel.userName
    
    TextField(
        value = userName,
        onValueChange = viewModel::updateName
    )
}

5. Производные состояния с derivedStateOf

Когда состояние зависит от других состояний, используйте derivedStateOf:

@Composable
fun DerivedStateExample() {
    var firstName by remember { mutableStateOf("") }
    var lastName by remember { mutableStateOf("") }
    
    val fullName = remember { derivedStateOf { "$firstName $lastName" } }
    
    Text(text = "Полное имя: ${fullName.value}")
}

6. Состояние в списках и коллекциях

Для изменяемых списков используйте специальные mutableState коллекции:

@Composable
fun TodoList() {
    // Автоматические уведомления об изменениях в списке
    val items = remember { mutableStateListOf<String>() }
    
    LazyColumn {
        items(items) { item ->
            Text(text = item)
        }
    }
    
    Button(onClick = { items.add("Новая задача") }) {
        Text("Добавить")
    }
}

Ключевые принципы:

  • Локализуйте состояние - храните состояние в ближайшем общем предке композиций, которые его используют
  • Поднимайте состояние вверх (State Hoisting) - когда несколько композиций используют одни данные
  • Используйте неизменяемые данные - создавайте новые объекты вместо модификации существующих
  • rememberSaveable для сохранения состояния при повороте экрана:
@Composable
fun StateSurvivalExample() {
    // Сохраняется в Bundle при изменении конфигурации
    var text by rememberSaveable { mutableStateOf("") }
}

Важное замечание: Никогда не изменяйте состояние напрямую внутри Compose-функции без использования реактивных API (mutableStateOf, StateFlow, etc.), так как это не вызовет рекомпозицию и UI не обновится.

Как сделать изменяемый стейт в Composable функции | PrepBro