Jetpack Compose là thư viện UI hiện đại của Android, giúp xây dựng giao diện một cách declarative (). Thay vì “vẽ” UI từng bước, bạn chỉ cần mô tả state hiện tại, và Compose sẽ tự động cập nhật UI tương ứng khi state thay đổi.
🔄 So sánh Imperative vs Declarative
Tiêu chí | Imperative | Declarative |
---|---|---|
Mô tả hành vi | Bạn viết từng bước xử lý | Bạn mô tả kết quả mong muốn |
UI cập nhật | Bạn cập nhật thủ công | UI tự cập nhật theo state |
Phong cách | Lập trình kiểu truyền thống | Lập trình hiện đại (React, Compose, SwiftUI) |
Quản lý state | Thường nằm ngoài UI | State tích hợp trong UI |
Dễ bảo trì | Khó khi UI phức tạp | Dễ mở rộng và test |
Công nghệ Android | XML + Java/Kotlin | Jetpack Compose |
Chính vì vậy, quản lý state là một phần cốt lõi và quan trọng trong mọi ứng dụng Compose.
🚀 Có những loại state nào trong Compose?
Dưới đây là các loại state phổ biến mà bạn sẽ thường xuyên gặp:
remember
– Lưu state trong vòng đời của composable.rememberSaveable
– Lưu state qua cả thay đổi cấu hình (rotation, backstack).ViewModel + StateFlow
– Quản lý state ở cấp màn hình / module lớn.CompositionLocal
– Chia sẻ giá trị toàn cục mà không truyền thủ công.derivedStateOf
– Tạo state dẫn xuất để tối ưu recomposition.rememberUpdatedState
– Giữ giá trị cập nhật mới nhất trong coroutine hoặc callback.
🔍 Phân tích chi tiết từng loại state
1. ✅ remember
Giữ giá trị trong lần gọi composable hiện tại. Khi recomposition xảy ra, giá trị vẫn được giữ nguyên.
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) }
Button(onClick = { count++ }) {
Text("Clicked $count times")
}
}
➡️ Dùng khi: Bạn chỉ cần giữ state trong vòng đời composable hiện tại (không cần survive qua rotation). Giá trị count sẽ bị reset khi mở màn hình mới, khi rotation .
2. 💾 rememberSaveable
Giống remember
, nhưng dùng được với các kiểu primitive và Serializable – giá trị vẫn giữ được sau khi xoay màn hình.
@Composable
fun RememberSaveableDemo() {
var name by rememberSaveable { mutableStateOf("") }
TextField(value = name, onValueChange = { name = it })
}
➡️ Dùng khi: Bạn muốn giữ lại dữ liệu đầu vào của người dùng khi thiết bị xoay, khi mở màn hình khác và quay lại.
3. 🧠 ViewModel + StateFlow
Sử dụng ViewModel
để tách logic ra khỏi UI và giữ state qua nhiều recomposition.
class CounterViewModel : ViewModel() {
private val _count = MutableStateFlow(0)
val count: StateFlow<Int> = _count.asStateFlow()
fun increment() {
_count.value++
}
}
@Composable
fun CounterWithViewModel(viewModel: CounterViewModel = viewModel()) {
val count by viewModel.count.collectAsState()
Button(onClick = { viewModel.increment() }) {
Text("Clicked $count times")
}
}
➡️ Dùng khi: Bạn cần quản lý logic, xử lý dữ liệu, hoặc chia sẻ state giữa nhiều composable.
4. 🌍 CompositionLocal
Cho phép bạn chia sẻ giá trị giữa các composable mà không cần truyền trực tiếp qua props.
val LocalUserName = compositionLocalOf { "Guest" }
@Composable
fun AppContent() {
CompositionLocalProvider(LocalUserName provides "John") {
WelcomeUser()
}
}
@Composable
fun WelcomeUser() {
Text("Hello, ${LocalUserName.current}")
}
➡️ Dùng khi: Cần chia sẻ giá trị toàn cục như theme, locale, session, user info…
5. ⚙️ derivedStateOf
Tạo state dẫn xuất từ state gốc, chỉ recompute khi giá trị phụ thuộc thay đổi. Giúp tối ưu hiệu năng.
@Composable
fun DerivedStateExample() {
var text by remember { mutableStateOf("") }
val isValid by remember {
derivedStateOf { text.length > = 5 }
}
Column {
TextField(value = text, onValueChange = { text = it })
Text(if (isValid) "Valid" else "Too short")
}
}
➡️ Dùng khi: Bạn có logic tính toán phụ thuộc vào state khác và muốn tránh recomposition không cần thiết.
6. 🔄 rememberUpdatedState
Giúp callback hoặc coroutine luôn sử dụng giá trị mới nhất thay vì bị giữ lại giá trị cũ khi khởi tạo.
@Composable
fun TimerWithMessage(message: String) {
val latestMessage by rememberUpdatedState(message)
LaunchedEffect(Unit) {
delay(5000)
Log.d("TAG", "After delay: $latestMessage")
}
}
➡️ Dùng khi: Bạn dùng coroutine hoặc listener dài hạn và muốn truy cập giá trị mới nhất từ state.
✅ Kết luận
Việc chọn đúng loại state sẽ giúp ứng dụng Compose của bạn mượt mà, dễ bảo trì và tránh bug không đáng có.
State Type | Khi nào nên dùng |
---|---|
remember | State đơn giản, không cần giữ khi config thay đổi |
rememberSaveable | Cần giữ state sau khi xoay màn hình |
ViewModel + StateFlow | Quản lý logic, xử lý và chia sẻ state |
CompositionLocal | Giá trị toàn cục (theme, user…) |
derivedStateOf | Tối ưu tính toán state dẫn xuất |
rememberUpdatedState | Đảm bảo callback hoặc coroutine luôn dùng dữ liệu mới nhất |