Sparround

Compose-da state idarəetməsi və side effect-lər

Side effect — composable-ın "UI emit etmək" işindən kənar hər şey: API çağırışı, snackbar, navigasiya, analytics. Recomposition istənilən sayda təkrarlana bildiyi üçün side effect birbaşa composable body-də yazılmaz — idarəli effect API-ları var:

  • LaunchedEffect(key) — composition-a girəndə coroutine başladır; key dəyişəndə restart, çıxanda cancel. "Ekran açılanda yüklə", "id dəyişəndə yenidən çək".
  • DisposableEffect(key) — qeydiyyat/təmizləmə cütü: listener əlavə et, onDispose-da çıxar.
  • rememberCoroutineScope — callback-lərdən (onClick) coroutine başlatmaq üçün scope.
  • SnapshotFlow — Compose state-ini Flow-a çevirir (məs. scroll mövqeyini izləmək).
  • derivedStateOf — başqa state-lərdən törənən dəyər; yalnız nəticə dəyişəndə recomposition.

ViewModel-dən state toplamaq üçün standart: collectAsStateWithLifecycle() — lifecycle STARTED olmayanda toplanma dayanır (resurs qənaəti).

kotlin
@Composable
fun TransactionDetailScreen(txId: String, viewModel: DetailViewModel = hiltViewModel()) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()
    val snackbarHostState = remember { SnackbarHostState() }
    val scope = rememberCoroutineScope()

    // txId dəyişəndə yenidən yüklə; ekrandan çıxanda cancel
    LaunchedEffect(txId) {
        viewModel.load(txId)
    }

    // Birdəfəlik event-lərin toplanması
    LaunchedEffect(Unit) {
        viewModel.messages.collect { msg ->
            snackbarHostState.showSnackbar(msg)
        }
    }

    // Callback-dən coroutine: suspend olan snackbar çağırışı
    Button(onClick = {
        scope.launch { snackbarHostState.showSnackbar("Kopyalandı") }
    }) { Text("Qəbzi kopyala") }
}

Effect API-larının hərəsi öz yerində

Tələ-sual: "API çağırışını niyə birbaşa composable body-də etmək olmaz?" — body hər recomposition-da icra olunur: bir kliklə 10 recomposition = 10 sorğu. Düzgün yer: ViewModel (init/metod) və ya LaunchedEffect. İkinci tələ: LaunchedEffect(Unit) vs LaunchedEffect(id) — Unit yalnız girişdə bir dəfə, id isə hər dəyişmədə restart deməkdir; səhv key seçimi ya köhnə data, ya artıq sorğu deməkdir.

🛠 Tapşırıq

Effect API-larını səhv işlədib nəticəsini gör:

  • API çağırışını (log ilə imitasiya) birbaşa composable body-də et və neçə dəfə çağırıldığını say; sonra LaunchedEffect-ə köçür.
  • LaunchedEffect(Unit) ilə LaunchedEffect(id)-ni müqayisə et: id dəyişəndə hansı yenilənir?
  • collectAsStateWithLifecycle ilə ViewModel state-ini topla və snackbar-ı SharedFlow-dan göstər.

Bitdi sayılır: "key-i nə üçün verirsən" sualına öz sayğacının rəqəmləri ilə cavab verirsənsə.

📚 Mənbələr və sənədlər