State Hoisting — bu Jetpack Compose-dagi naş bo'lib, unda holat bola Composable funksiyasidan ota funksiyasiga chiqariladi, bola esa ma'lumotlarni parametrlar orqali oladi va o'zgarishlar haqida callback-lar orqali xabar beradi. Bu bir yo'nalishli ma'lumot oqimi (UDF) prinsipining amalga oshirilishi bo'lib, unda holat yuqoriga ko'tariladi, hodisalar esa pastga tushadi. Google Android Developers, 2026 ma'lumotlariga ko'ra, State Hoisting komponentlarni qayta ishlatiladigan, sinab ko'riladigan va bashorat qilinadigan qiladi.
Asosiy ma'lumotlar
State Hoisting (holatni ko'tarish) — bu naş bo'lib, unda Composable funksiyasi holatga ega emas, balki uni tashqaridan oladi. Funksiya ichida var o'rniga ikkita parametr ishlatiladi: ko'rsatish uchun qiymat va o'zgarishlarni boshqarish uchun lambda-callback. Texnik jihatdan, bu bola komponentning stateless (o'z holati yo'q), ota komponentning esa stateful (holatga ega) bo'lishini anglatadi.
Misol: Material3 dan TextField komponenti kiritilgan matnni o'zida saqlamaydi. U value: String va onValueChange: (String) -> Unit ni qabul qiladi. TextField ni chaqiradigan ota var value by remember { mutableStateOf("") } ni e'lon qiladi va value hamda onValueChange ni uzatadi. Bu klassik State Hoisting: TextField — oddiy komponent (faqat ko'rsatadi va kiritish haqida xabar beradi), ota — aqlli (holatga ega).
Stateless vs Stateful: Stateless komponentni sinash oson — u ichki holatga bog'liq emas, uning xatti-harakati to'liq kirish parametrlari bilan belgilanadi. Stateful komponent tez prototiplash uchun qulay, lekin qayta ishlatish qiyinroq — u bir ma'lumot manbaiga qattiq bog'langan. State Hoisting tanlov beradi: har qanday komponentni holatni yuqoriga chiqarib, stateless qilish mumkin.
UDF (Unidirectional Data Flow) — bu arxitektura prinsipi bo'lib, unda ma'lumotlar bir yo'nalishda harakatlanadi: haqiqat manbasidan (ViewModel yoki ota Composable) UI ga, hodisalar esa teskari yo'nalishda. State Hoisting alohida komponentlar darajasida UDF ning amalga oshirilishidir. Har bir komponent o'z holatini qachon va qanday o'zgartirishni o'zi hal qilishi o'rniga, u hodisa haqida otaga xabar beradi, ota esa holatni qanday o'zgartirishni hal qiladi.
UDF ning afzalliklari: bashorat qilish — holat faqat bir joyda o'zgaradi, bu race condition larni yo'q qiladi; traceability — chaqiruv steki bo'yicha o'zgarishlar zanjirini tiklash mumkin; sinash — stateful mantiqni alohida sinfga chiqarib, UI siz sinash mumkin. Katta loyihalarda UDF ni State Hoisting bilan birgalikda ishlatish de-fakto standartdir.
Yagona haqiqat manbai (Single Source of Truth) — UDF ga hamroh bo'lgan yana bir prinsip. Holatning har bir bo'lagi aniq bir manbaga ega. Agar ikki komponent bir xil holatdan foydalansa, manba umumiy bo'lishi kerak (ViewModel yoki umumiy ota darajasida). State Hoisting manbaning iyerarxiyada yuqoriroq bo'lishini va holatning takrorlanmasligini kafolatlaydi.
| Yo'nalish | Nima uzatiladi | Qanday amalga oshirilgan |
|---|---|---|
| Pastga (ota → bola) | Ko'rsatiladigan qiymat | Parametr value: T |
| Yuqoriga (bola → ota) | O'zgarish hodisasi | Parametr onValueChange: (T) -> Unit |
Asosiy qoida: holat unga ehtiyoji bor barcha komponentlar uchun yetarli bo'lgan minimal darajaga ko'tarilishi kerak. Agar holat faqat bitta komponent ichida ishlatilsa — uni lokal qoldiring. Agar ikki qo'shni komponent bir xil holatga ehtiyoj sezsa — umumiy otaga ko'taring. Agar holat butun ekran uchun kerak bo'lsa — ViewModel ga ko'taring.
Minimal ko'tarish qoidasi keraksiz murakkablikning oldini oladi. Matn maydonining holatini ViewModel ga ko'tarishning ma'nosi yo'q, agar u faqat bitta ekran ichida ishlatilsa va Activity qayta yaratilganda saqlanmasa. Ekran aylanishidan omon qolishi kerak bo'lgan, ammo biznes mantiqqa kerak bo'lmagan UI holati uchun ViewModel o'rniga ekran otasi darajasida rememberSaveable dan foydalaning.
Qachon ViewModel ga ko'tarish kerak: agar holat Activity qayta yaratilganda saqlanishi kerak bo'lsa, agar bir nechta ekranga kerak bo'lsa, agar holat o'zgarishi biznes mantiqni (tarmoq so'rovlari, ma'lumotlar bazasi) ishga tushirsa. ViewModel darajasidagi State Hoisting MVVM arxitekturasidagi odatiy naş bo'lib, unda UI qatlami stateless, ViewModel esa stateful dir.
// ❌ Yomon: komponent o'z holatiga ega
@Composable
fun BadTextField(label: String) {
var text by remember { mutableStateOf("") }
TextField(value = text, onValueChange = { text = it }, label = { Text(label) })
}
// ✅ Yaxshi: State Hoisting — holat otada
@Composable
fun GoodTextField(value: String, onValueChange: (String) -> Unit, label: String) {
TextField(value = value, onValueChange = onValueChange, label = { Text(label) })
}
// Ishlatish: ota holatga ega
@Composable
fun Form() {
var name by rememberSaveable { mutableStateOf("") }
GoodTextField(value = name, onValueChange = { name = it }, label = "Name")
}
Kirish ekranini ko'rib chiqaylik, unda ikkita maydon (email, parol) va tugma bor. Har uch komponent holatni State Hoisting orqali oladi: email va parol ota tomonidan boshqariladi, tugma enabled holatini qiymat sifatida oladi.
// Ekran darajasida State Hoisting
@Composable
fun LoginScreen(viewModel: LoginViewModel) {
val uiState by viewModel.uiState.collectAsState()
Column(modifier = Modifier.padding(16.dp)) {
// Email maydoni — lambda orqali State Hoisting
EmailField(
email = uiState.email,
onEmailChange = { viewModel.onEmailChanged(it) }
)
// Parol maydoni — xuddi shunday
PasswordField(
password = uiState.password,
onPasswordChange = { viewModel.onPasswordChanged(it) }
)
// Tugma — faqat enabled oladi (faqat o'qish)
LoginButton(enabled = uiState.isFormValid, onClick = viewModel::login)
}
}
// Stateless komponent: email + callback oladi
@Composable
fun EmailField(email: String, onEmailChange: (String) -> Unit) {
OutlinedTextField(
value = email,
onValueChange = onEmailChange,
label = { Text("Email") },
singleLine = true
)
}
// Stateless tugma komponenti
@Composable
fun LoginButton(enabled: Boolean, onClick: () -> Unit) {
Button(onClick = onClick, enabled = enabled) {
Text("Kirish")
}
}
EmailField va PasswordField — to'liq stateless. Ularni istalgan ekranda, istalgan ma'lumot manbaiga ulab qayta ishlatish mumkin. LoginButton enabled ni faqat o'qish uchun oladi — bu State Hoisting ning yana bir shakli bo'lib, unda holat ko'tarilmaydi (tugma o'zini o'zi yoqa olmaydi), balki tayyor holda uzatiladi. Bunday yondashuv minimal komponent bog'lanishi bilan maksimal moslashuvchanlikni beradi.
Har bir holatni ko'tarish shart emas. Lokal holat (Composable ichidagi State) oqlanadi, agar: ma'lumotlar faqat bitta komponent ichida kerak bo'lsa, qo'shni elementlarga ta'sir qilmasa, ma'lum bir bo'limning rekompozitsiyasidan omon qolishi shart bo'lmasa. Masalan, animatsiya holati, kiritish maydoni fokusi, joriy skroll pozitsiyasi — ularni lokal saqlash maqsadga muvofiq.
Qachon State Hoisting zarur: holat bir nechta bola komponentlar tomonidan ishlatilsa; bir boladagi o'zgarish boshqasida aks etishi kerak bo'lsa; holat o'zgarishi mantiqini UI dan alohida sinash kerak bo'lsa; holat Activity qayta yaratilganda saqlanishi kerak bo'lsa. Bunday hollarda lokal holat ma'lumotlarning takrorlanishi va nomuvofiqligiga olib keladi.
Gibrid yondashuv: minimal holatni lokal saqlang, qolganini ko'taring. Compose qoidasi: “holatni kerakli darajada yuqori va imkon qadar past ko'taring”. Amalda bu lokal remember bilan boshlash va faqat boshqa komponentdan kirish ehtiyoji paydo bo'lganda darajani ko'tarishni anglatadi. State Hoisting ni profilaktik qo'llamang — bu kodni keraksiz murakkablashtiradi.
Tez-tez so'raladigan savollar
State Hoisting — bu UI komponentlari darajasidagi naş. ViewModel — biznes mantiq uchun arxitektura qatlamidir. State Hoisting holatni ota Composable darajasiga, ekran darajasiga yoki ViewModel ga ko'tarishi mumkin. ViewModel — Activity qayta yaratilishidan omon qolishi kerak bo'lgan holat uchun eng yuqori ko'tarish nuqtasidir.
Stateless komponent oddiygina qiymatlarni uzatish orqali sinanadi. Composable ni kerakli parametrlar bilan chaqiring va ComposeTestRule orqali ko'rsatilishini tekshiring. Holat o'zgarishi ota yoki ViewModel darajasida — UI dan alohida sinanadi. Bu testlarni ancha soddalashtiradi: komponent ichida rekompozitsiyani simulyatsiya qilish shart emas.
Ha, bu keng tarqalgan amaliyot. Agar komponent faqat ma'lumotlarni o'zgartirmasdan ko'rsatishi kerak bo'lsa — State<T> (faqat o'qish) uzating. Komponent o'zgarishlarga obuna bo'ladi, lekin ularni boshlay olmaydi. Bu inkapsulyatsiyani kuchaytiradi va ma'lumotlarni istalmagan mutatsiyalardan himoya qiladi.
Chuqur uzatish uchun CompositionLocal yoki ota Composable parametrlari orqali uzatishdan foydalaning. Agar holat butun ekran uchun kerak bo'lsa — uni ViewModel ga chiqaring va collectAsState() dan foydalaning. 5+ daraja orqali uzatish — noto'g'ri arxitektura belgisi; komponent iyerarxiyasini qayta ko'rib chiqing.
State Hoisting rekompozitsiyalar sonini biroz oshirishi mumkin, chunki otadagi o'zgarish barcha bolalarni qayta kompozitsiya qilishi mumkin. O'zgarishlarni filtrlash uchun derivedStateOf va LazyColumn da nuqtali yangilanishlar uchun keys dan foydalaning. Aksariyat stsenariylarda State Hoisting ning yuki, saqlanishilik foydasiga nisbatan ahamiyatsiz darajada kichikdir.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.