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

Какие знаешь еще эффекты помимо DisposableEffect?

1.6 Junior🔥 203 комментариев
#Dependency Injection

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

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

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

Эффекты в Compose: Beyond DisposableEffect

В Jetpack Compose эффекты — это функции, которые позволяют выполнять side-эффекты в рамках композиции. Помимо DisposableEffect, существует несколько других ключевых эффектов, каждый из которых решает определённые задачи. Вот основные из них:

1. LaunchedEffect

Запускает приостанавливаемую функцию (coroutine) внутри области видимости композиции. Автоматически отменяется при выходе из композиции или изменении ключей.

@Composable
fun TimerExample() {
    var time by remember { mutableStateOf(0) }
    
    LaunchedEffect(key1 = Unit) {
        while (isActive) {
            delay(1000)
            time++
        }
    }
    
    Text(text = "Прошло $time секунд")
}

2. SideEffect

Выполняет код при каждой успешной рекомпозиции. Используется для синхронизации состояния Compose с внешними системами, не поддерживающими наблюдаемые изменения.

@Composable
fun AnalyticsTracker(screenName: String) {
    SideEffect {
        // Отправка аналитики при каждой рекомпозиции
        Analytics.logScreenView(screenName)
    }
}

3. rememberCoroutineScope

Создает CoroutineScope, привязанную к области видимости композиции. Отменяется при выходе из композиции. Полезен для запуска корутин из callback-ов (например, onClick).

@Composable
fun CoroutineExample() {
    val scope = rememberCoroutineScope()
    var data by remember { mutableStateOf<String?>(null) }
    
    Button(onClick = {
        scope.launch {
            data = fetchData()
        }
    }) {
        Text("Загрузить данные")
    }
}

4. rememberUpdatedState

Создает ссылку на значение, которое может изменяться со временем, но не вызывает рестарт эффекта при изменении. Полезен для длительных операций, где нужно использовать актуальное значение.

@Composable
fun RememberUpdatedExample(onTimeout: () -> Unit) {
    val currentOnTimeout by rememberUpdatedState(newValue = onTimeout)
    
    LaunchedEffect(key1 = Unit) {
        delay(3000)
        currentOnTimeout() // Всегда вызовет актуальный callback
    }
}

5. produceState

Преобразует внешние источники данных в State Compose. Автоматически запускает и останавливает producer-корутину.

@Composable
fun ProduceStateExample(userId: String): State<Result<User>> {
    return produceState(initialValue = Result.Loading, userId) {
        val user = userRepository.getUser(userId)
        value = Result.Success(user)
    }
}

6. derivedStateOf

Создает производное состояние, которое вычисляется на основе других состояний. Оптимизирует рекомпозиции, вычисляясь только при изменении зависимостей.

@Composable
fun DerivedStateExample(items: List<String>) {
    val scrollState = rememberLazyListState()
    
    val showButton by remember {
        derivedStateOf {
            scrollState.firstVisibleItemIndex > 0
        }
    }
    
    if (showButton) {
        Button(onClick = { /* Действие */ }) {
            Text("Вверх")
        }
    }
}

7. snapshotFlow

Преобразует State Compose в Flow. Позволяет реагировать на изменения состояния в корутинах или других частях приложения.

@Composable
fun SnapshotFlowExample(searchQuery: String) {
    val scope = rememberCoroutineScope()
    
    LaunchedEffect(key1 = searchQuery) {
        snapshotFlow { searchQuery }
            .debounce(300)
            .distinctUntilChanged()
            .collect { query ->
                scope.launch {
                    viewModel.search(query)
                }
            }
    }
}

Ключевые различия между эффектами

  • LaunchedEffect vs DisposableEffect: Оба имеют ключи и вызывают dispose, но LaunchedEffect предназначен для корутин, а DisposableEffect — для любых ресурсов.
  • SideEffect vs DisposableEffect: SideEffect не имеет dispose-логики и выполняется при каждой рекомпозиции, в то время как DisposableEffect управляет жизненным циклом ресурсов.
  • produceState vs LaunchedEffect: produceState специализирован на преобразовании данных в State, в то время как LaunchedEffect более универсален.

Практические рекомендации

  1. Используйте LaunchedEffect для одноразовых асинхронных операций при изменении ключей
  2. Применяйте DisposableEffect для управления подписками, слушателями и другими ресурсами
  3. Выбирайте SideEffect для синхронизации с внешними системами без состояния
  4. Оптимизируйте с derivedStateOf вычисления, зависящие от нескольких состояний
  5. Используйте snapshotFlow для сложных реактивных цепочек на основе состояния Compose

Понимание этих эффектов позволяет эффективно управлять side-эффектами, ресурсами и асинхронными операциями в Compose, создавая отзывчивые и эффективные UI.

Какие знаешь еще эффекты помимо DisposableEffect? | PrepBro