remember — ay isang function sa Jetpack Compose na nagbibigay-daan sa pagpapanatili ng halaga sa pagitan ng recomposition, na pumipigil sa pag-reset ng estado sa bawat pag-restart ng Composable function. Kung wala ang remember, lahat ng variable na idineklara sa loob ng function ay mare-reset sa bawat pag-update ng UI, na ginagawang hindi matatag at walang silbi ang estado. Ayon sa Google Android Developers, 2026, ang tamang paggamit ng remember ay ang pundasyon ng wastong pamamahala ng estado sa deklaratibong UI.
Mga pangunahing punto
remember — ay isang built-in na function ng Jetpack Compose mula sa package na androidx.compose.runtime na lumilikha ng isang bagay na nagpapanatili ng halaga nito sa pagitan ng magkakasunod na tawag ng Composable function. Teknikal, gumagana ang remember sa mga slot — mga espesyal na memory cell na inilaan para sa bawat posisyon ng tawag ng function sa UI tree. Hangga't nananatili ang function sa komposisyon (hindi tinanggal sa pamamagitan ng if condition), ang remember ay magbabalik ng naka-save na halaga sa bawat recomposition.
Ang syntax ng remember ay simple: sa loob ng curly braces ay tinutukoy ang block ng pagkalkula ng paunang halaga. Ang block ay isinasagawa nang isang beses lamang — sa unang komposisyon ng function. Lahat ng kasunod na recomposition ay nagbabalik ng naka-save na halaga, nang hindi tinatawag muli ang block. Gayunpaman, kung ang isang susi (parameter key) ay tinukoy, ang block ay muling isasagawa kapag nagbago ang susi, na nagpapahintulot sa muling pagkalkula ng halaga batay sa input data.
Ang remember ay hindi mahika ng Kotlin — ito ay isang simpleng function na may parameter na key at calculation lambda. Ang panloob na implementasyon nito ay gumagamit ng Composer para magbasa at magsulat sa mga slot. Ang Kotlin compiler, kapag nakakakita ng tawag sa remember, ay bumubuo ng code na uma-access sa kasalukuyang CompositionContext at namamahala ng mga slot. Ito ay nangangahulugan na ang remember ay maaari lamang tawagin sa loob ng Composable function o ibang function sa konteksto ng komposisyon.
Sa Jetpack Compose mayroong tatlong pangunahing variant ng remember, bawat isa ay may sariling layunin. Ang base remember ay nagpapanatili ng halaga lamang sa memorya ng kasalukuyang proseso — sa pag-ikot ng screen (config change), muling ginagawa ng Compose ang Composition at lahat ng remember values ay nire-reset. Para sa pagpapanatili ng data sa mga pagbabago sa configuration at paghinto ng proseso, ginagamit ang rememberSaveable.
rememberSaveable ay nagsi-serialize ng halaga sa Bundle sa pamamagitan ng SavedStateHandle o Parcelable mechanism. Ito ay nagbibigay-daan upang makaligtas sa pag-ikot ng screen, tawag na “Huwag panatilihin ang mga aktibidad” at kahit pansamantalang pag-minimize ng app. Gayunpaman, ang rememberSaveable ay nagpapataw ng mga paghihigpit sa uri ng data na iniimbak: dapat silang maging primitives, Parcelable, Serializable, o sumusuporta sa Saver converter.
derivedStateOf — ay hindi mekanismo ng pag-iimbak, kundi isang pag-optimize. Lumilikha ito ng State na ang halaga ay kinakalkula batay sa iba pang State objects. Ang derivedStateOf ay tumutugon sa mga pagbabago sa source states, ngunit muling kinakalkula ang halaga lamang kapag may mga subscriber. Kung ang kasalukuyang recomposition ay hindi nagbabasa ng derivedStateOf, ang pagkalkula ay hindi isinasagawa, na nakakatipid ng mga mapagkukunan sa mga madalas ngunit hindi kinakailangang pag-update.
@Composable
fun RememberVariants() {
// 1. Pangunahing remember: nananatili hanggang umalis sa komposisyon
val createdAt = remember { System.currentTimeMillis() }
// 2. rememberSaveable: nakakaligtas sa pag-ikot ng screen
var username by rememberSaveable { mutableStateOf("") }
// 3. derivedStateOf: kinakalkula lamang kapag kinakailangan
val isButtonVisible = remember {
derivedStateOf { username.length() > 3 }
}
Text("Nilikha: $createdAt")
TextField(value = username, onValueChange = { username = it })
if (isButtonVisible.value) {
Text("Ipapakita ang pindutan")
}
}
Ang pagpili sa pagitan ng remember at rememberSaveable ay depende sa kung gaano kritikal ang pagpapanatili ng data sa mga pagbabago sa configuration. Para sa pansamantalang estado na ang pagkawala sa pag-ikot ay hindi mahalaga (animation, kasalukuyang posisyon ng scroll, focus state) — sapat na ang ordinaryong remember. Para sa kritikal na data (text sa form, mga napiling item, mga checkbox) — gamitin ang rememberSaveable.
Pagganap ng rememberSaveable ay mas mababa kaysa sa ordinaryong remember, dahil nangangailangan ito ng serialization sa Bundle. Gamitin ang rememberSaveable lamang para sa data na dapat makaligtas sa muling paggawa ng Activity. Para sa lahat ng iba pa — ordinaryong remember. Ang labis na paggamit ng rememberSaveable ay humahantong sa pagbagal sa pag-ikot ng screen at paglipat sa pagitan ng mga app.
Kung nagtatrabaho ka sa mga klase na hindi sumusuporta sa Parcelable o Serializable, gamitin ang Saver — isang converter na tumutukoy kung paano i-save at i-restore ang isang bagay. Ang Saver ay inilalarawan ng isang pares ng lambda: save (nagko-convert ng bagay sa isang nai-save na uri) at restore (nagre-restore ng bagay mula sa naka-save na data). Ang standard na Saver ay naipatupad na para sa mutableStateListOf at mutableStateMapOf.
| Katangian | remember | rememberSaveable |
|---|---|---|
| Pagpapanatili sa recomposition | Oo | Oo |
| Pagpapanatili sa pag-ikot | Hindi | Oo |
| Pagpapanatili sa paghinto ng proseso | Hindi | Oo |
| Mga kinakailangan sa uri | Anuman | Parcelable, Serializable, Saver |
| Pagganap | Mataas | Katamtaman |
Tingnan natin ang isang tipikal na senaryo — screen ng pag-edit ng profile, kung saan ginagamit ang remember para sa maraming layunin: pag-iimbak ng estado ng mga field ng form, pagkalkula ng mga derived value, at pag-cache ng mga operasyong computationally mahal.
data class ProfileUiState(
val name: String = "",
val bio: String = "",
val isSaving: Boolean = false
)
@Composable
fun ProfileEditor() {
var state by rememberSaveable { mutableStateOf(ProfileUiState()) }
val isValid = remember {
derivedStateOf { state.name.isNotBlank() && state.bio.length() <= 500 }
}
val bioWarning = remember(state.bio) {
if (state.bio.length() > 400) {
"${500 - state.bio.length} chars left"
} else null
}
Column(modifier = Modifier.padding(16.dp)) {
OutlinedTextField(
value = state.name,
onValueChange = { state = state.copy(name = it) },
label = { Text("Pangalan") }
)
OutlinedTextField(
value = state.bio,
onValueChange = { state = state.copy(bio = it) },
label = { Text("Tungkol sa") }
)
bioWarning?.let { Text(it, color = MaterialTheme.colorScheme.error) }
Button(onClick = { /* save */ },
enabled = isValid.value) {
Text("I-save")
}
}
}
Sa halimbawa, ang estado ay nai-save sa pamamagitan ng rememberSaveable — sa pag-ikot ng screen ang teksto ay hindi mawawala. Ang isValid ay kinakalkula sa pamamagitan ng derivedStateOf, na pumipigil sa mga hindi kinakailangang kalkulasyon sa recomposition. Ang bioWarning ay gumagamit ng remember na may susi na bio — ito ay isang mahal na kalkulasyon (opsyonal, para sa demonstrasyon) na muling kinakalkula lamang kapag nagbago ang bio, hindi sa bawat recomposition.
Ang mga derived state ay mga halaga na kinakalkula mula sa iba pang State objects. Sa halip na kalkulahin ang mga ito sa bawat recomposition at mag-aksaya ng CPU sa magkaparehong resulta, ang remember na may derivedStateOf ay kinakalkula ang halaga lamang kapag nagbago ang mga source. Ito ay lalong kapaki-pakinabang para sa pag-filter, pag-uuri, at pagsasama-sama ng data.
remember na may mga susi (remember(key) { calculation }) — isa pang mekanismo ng pag-optimize. Kung ang susi ay hindi nagbago mula noong nakaraang recomposition, ang block ng pagkalkula ay hindi isinasagawa at ang naka-cache na halaga ay ibabalik. Ito ay maginhawa para sa pag-cache ng mga bagay na ang paglikha ay mahal: pag-format ng mga petsa, pag-parse ng JSON, paglikha ng malalaking hindi nababagong koleksyon.
@Composable
fun SearchResults(allItems: List<Item>, query: String) {
// derivedStateOf: filter ay muling kinakalkula lamang kapag nagbago ang input
val filtered = remember {
derivedStateOf {
allItems.filter { it.title.contains(query, true) }
}
}
// remember na may susi: na-format na estadistika ay muling kinakalkula lamang sa pagbabago ng query
val statsText = remember(query) {
"Results for query \"$query\": ${filtered.value.size}"
}
Text(statsText)
LazyColumn {
items(filtered.value, key = { it.id }) { item ->
Text(item.title)
}
}
}
Ang filtered — ay isang derivedStateOf na awtomatikong muling kinakalkula kapag nagbago ang allItems o query. Ang statsText ay gumagamit ng remember(query) — ang mahal na pag-format ng string ay isinasagawa lamang kapag nagbago ang query sa paghahanap. Ang kombinasyon ng derivedStateOf at remember na may mga susi ay nagbibigay ng maximum na pagganap: ang derived state ay kinakalkula lamang kapag kinakailangan, at ang mga kumplikadong bagay ay na-cache hanggang sa magbago ang susi.
Mga madalas itanong
Hindi, ang remember — ay isang function mula sa package na compose.runtime na nangangailangan ng CompositionContext. Ito ay maaari lamang tawagin sa loob ng @Composable function o sa loob ng ibang function na tinawag mula sa Composable. Para sa pag-iimbak ng data sa labas ng komposisyon, gamitin ang ViewModel.
Kung walang susi, ang remember ay kinakalkula ang block nang isang beses lamang — sa unang komposisyon. Lahat ng kasunod na recomposition ay nagbabalik ng naka-save na halaga. Kung kailangan mong muling kalkulahin ang halaga kapag nagbago ang data, tiyaking tukuyin ang mga ito bilang susi: remember(data) { compute(data) }.
Walang direktang pag-reset ng remember. Ang tanging paraan ay alisin ang function mula sa komposisyon (halimbawa, sa pamamagitan ng pagtatago gamit ang if condition) at pagkatapos ay ipakita muli ito. Sa muling pagpasok, ang remember block ay isasagawa muli, na lilikha ng bagong paunang halaga.
Ang remember ay nag-iimbak ng estado sa slot ng Composable function at nabubuhay hangga't ang function ay nasa komposisyon. Ang ViewModel ay nabubuhay hangga't nabubuhay ang lifecycle ng screen. Ang ViewModel ay nananatili sa pag-ikot at ginagamit para sa lohika ng negosyo. Ang remember — ay para sa lokal na UI state na hindi kailangan sa labas ng isang function.
Oo, ang remember ay gumagana nang tama sa @Preview Composable function, dahil ang Preview ay lumilikha ng isang ganap na CompositionContext. Gayunpaman, ang rememberSaveable ay maaaring hindi gumana nang tama sa Preview, dahil ang SavedStateHandle ay maaaring wala sa kapaligiran ng preview.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din