mutableStateOf: paglikha ng napapansing estado at reaktibidad ng Compose

May-akda: IT Sectr Nai-publish: 2026-06-28 Oras ng pagbabasa: 7 min

mutableStateOf ay isang function sa Jetpack Compose na lumilikha ng lalagyan ng nababagong napapansing estado. Kapag nagbago ang halaga sa loob ng lalagyann ito, awtomatikong sinisimulan ng Compose ang recomposisyon ng lahat ng bahagi na bumabasa ng estadong ito. Kung wala ang mutableStateOf, hindi magagawa ng UI na mag-update nang reaktibo sa mga pagbabago ng datos. Ayon sa Google Android Developers, 2026, ang mutableStateOf ay pangunahing bloke ng gusali para sa lokal na estado sa Compose.

Mga Pangunahing Punto

  • mutableStateOf ay lumilikha ng lalagyan ng MutableState na sinusubaybayan ng Compose Runtime
  • Recomposisyon ay awtomatikong nasisimula kapag nagbago ang value ng State object na ito
  • Delegasyon sa pamamagitan ng var ay nagpapahintulot sa paggamit ng mutableStateOf nang hindi ginagamit ang .value
  • Mga Susi sa remember(mutableStateOf) ay hindi kailangan — ang State mismo ang nag-aabiso sa Compose ng mga pagbabago
  • Sistema ng Snapshot ay ginagarantiyado ang pagkakapare-pareho ng pagbasa sa multi-thread na kapaligiran

Ano ang mutableStateOf sa Jetpack Compose

mutableStateOf ay isang function mula sa package na compose.runtime na lumilikha ng MutableState<T> na bagay na nag-iimbak ng halaga at maaaring mag-abiso sa Compose Runtime tungkol sa mga pagbabago. Lagda: fun <T> mutableStateOf(value: T, policy: SnapshotMutationPolicy<T> = structuralEquality()): MutableState<T>. Ang parametrong policy ay tumutukoy kung kailan ang pagbabago ay itinuturing na makabuluhan — sa estruktural na pagkakapantay-pantay, sa referensyal na pagkakapantay-pantay, o hindi kailanman.

Ang MutableState ay isang interface na may iisang pag-aari na value: getter para sa pagbasa at setter para sa pagsulat. Kapag tinawag ang setter, itinatala ng Compose Runtime ang pagbabago sa isang snapshot at minamarkahan ang lahat ng Composable function na bumabasa ng State variable na ito bilang nangangailangan ng recomposisyon. Ang prosesong ito ay nangyayari nang sabay-sabay sa loob ng isang snapshot cycle, na nag-aalis ng mga intermediate na estado sa mga kaskad na pagbabago.

Parameter policy — ang pangalawang argumento ng mutableStateOf, na tumutukoy sa pag-uugali sa paghahambing. Ang structuralEquality() ay sinusuri ang equals() — ito ang default na pag-uugali. Ang referentialEquality() ay sinusuri ang === (referensyal na pagkakapantay-pantay). Ang neverEqual() ay itinuturing ang bawat pagtatalaga bilang pagbabago. Ang pagpili ng policy ay nakakaapekto kung ang recomposisyon ay masisimula sa pagtatalaga ng parehong halaga.

Sintaks at mga paraan ng deklarasyon ng mutableStateOf

Ang pinakasimpleng paraan upang ideklara ang napapansing estado ay ang paggamit ng mutableStateOf na may remember. Kung wala ang remember, sa bawat recomposisyon ay lilikha ng bagong State at lahat ng nakaraang pagbabago ay mawawala. Ginagarantiyahan ng remember na ang parehong MutableState ay makakaligtas sa isang serye ng recomposisyon hangga't ang Composable function ay nananatili sa komposisyon.

kotlin
@Composable
fun Counter() {
    // Walang delegasyon: pagbasa/pagsulat sa pamamagitan ng .value
    val count = remember { mutableStateOf(0) }
    Button(onClick = { count.value++ }) {
        Text("Count: ${count.value}")
    }
}

@Composable
fun CounterDelegated() {
    // May delegasyon: var + by = Property Delegation
    var count by remember { mutableStateOf(0) }
    Button(onClick = { count++ }) {
        Text("Count: $count")
    }
}

Ang pagkakaiba sa pagitan ng dalawang variant ay sintaktik. Property Delegation (by) ay gumagamit ng kombensyon ng Kotlin: ang kompiler ay lumilikha ng mga tawag sa getValue() at setValue() para sa pagbasa at pagsulat. Ito ay katumbas ng direktang pag-access sa count.value, ngunit mukhang nagtatrabaho sa isang ordinaryong variable. Ang parehong variant ay functional na magkapareho: sinusubaybayan ng Compose ang pagbasa sa getter at pagsulat sa setter anuman ang anyo ng pagsulat.

AnyoCodePagbasaPagsulat
Walang delegasyonval count = mutableStateOf(0)count.valuecount.value = n
May delegasyonvar count by mutableStateOf(0)countcount = n

Mga Delegadong Pag-aari at var

Ang mekanismo ng mga delegadong pag-aari ng Kotlin ay hindi tampok ng Compose, kundi isang built-in na kakayahan ng wika. Ang anumang klase ay maaaring magpatupad ng mga operator na getValue(thisRef, property) at setValue(thisRef, property, value), pagkatapos ang instance nito ay maaaring gamitin sa keyword na by. Ganito eksaktong gumagana ang MutableState: ang getValue ay nagbabalik ng kasalukuyang halaga, at ang setValue ay nagtatalaga ng bago.

Mahalagang pagkakaiba: val at var. Ang mutableStateOf ay maaaring italaga sa parehong val at var. Sa kaso ng val (val count = mutableStateOf(0)), ang MutableState object mismo ay hindi nababago, ngunit ang pag-aari nitong value ay maaaring baguhin. Sa kaso ng var (var count by mutableStateOf(0)), ang delegasyon ay lumilikha ng ilusyon ng pagtatrabaho sa isang primitibo, ngunit sa katotohanan ang setter ay tumatawag ng setValue sa MutableState. Ang pagpili sa pagitan ng val at var ay isang pagpili sa pagitan ng tahasan at implicit na pag-access sa .value.

State Delegation ay sintaktik na asukal na nagpapasimple ng code, ngunit hindi nagbabago ng mekanika. Ang Kotlin compiler ay nagta-transpile ng var x by mutableStateOf(0) sa getter/setter na tumatawag sa mutableStateOf.getValue() at mutableStateOf.setValue(). Sa nabuong bytecode, walang pagkakaiba sa pagitan ng val at var na may by — pareho silang gumagana sa pamamagitan ng parehong lalagyan ng MutableState.

kotlin
    // Custom na delegasyon para sa Compose State
class ValidatedState<T>(initialValue: T) {
    private val state = mutableStateOf(initialValue)

    operator fun getValue(thisRef: Any?, property: KProperty<*>) = state.value

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        if (value != state.value) {
            state.value = value
        }
    }
}

@Composable
fun Test() {
    var text by remember { ValidatedState("") }
}

Sistema ng Snapshot: paano gumagana ang mutableStateOf sa loob

Snapshot ay isang mekanismo ng Compose Runtime na ginagarantiyahan ang pagkakapare-pareho ng pagbasa ng State sa magkasabay na mga pagbabago. Kapag ang Composable function ay bumabasa ng mutableStateOf, itinatala ng snapshot ang kasalukuyang halaga. Kung sa panahon ng komposisyon ang isa pang pagbabago ay sumulat sa parehong State, nakikita ng snapshot ang pagsulat, ngunit hindi pinapayagan ang pagbasa ng hindi pare-parehong datos — ang pagbasa ay palaging nagbabalik ng halaga na napapanahon sa sandali ng pagsisimula ng snapshot.

Kapag tinawag ang setter na mutableStateOf.value = newValue, hindi agad sinisimulan ng Compose Runtime ang recomposisyon. Sa halip, ang pagbabago ay itinatala sa kasalukuyang snapshot. Kapag inilapat ang snapshot (sa hangganan ng frame), dumadaan ang Compose sa listahan ng mga binagong State at minamarkahan ang mga bahaging bumabasa bilang Invalid. Sa susunod na frame lamang masisimula ang recomposisyon. Ito ay ginagarantiyahan na ang UI ay hindi muling iguguhit ng maraming beses sa mga kaskad na pagbabago.

Global at lokal na snapshot: bilang default, ang mutableStateOf ay gumagana sa global snapshot na awtomatikong inilalapat. Maaaring lumikha ng lokal na snapshot sa pamamagitan ng Snapshot.takeSnapshot() para sa nakahiwalay na pagbasa nang walang mga side effect. Ito ay ginagamit sa loob ng Modifier, kung saan kailangang basahin ang State ngunit hindi kailangang mag-subscribe sa mga pagbabago. Ang pamamaraang ito ay nag-o-optimize ng pagganap at pumipigil sa hindi inaasahang recomposisyon.

Mga halimbawa ng paggamit ng mutableStateOf

Isaalang-alang natin ang isang tunay na senaryo — isang login form na may tatlong field: email, password, at katayuan ng pag-load. Lahat ng tatlong field ay gumagamit ng mutableStateOf, ngunit may iba't ibang policy at iba't ibang pagkaka-nest. Ang email ay gumagamit ng delegasyon, ang password — direktang pag-access.

kotlin
data class LoginState(
    val email: String = "",
    val password: String = "",
    val isLoading: Boolean = false,
    val error: String? = null
)

@Composable
fun LoginForm(onLogin: (String, String) -> Unit) {
    // Nag-iisang State para sa form, policy = referentialEquality
    var formState by remember {
        mutableStateOf(LoginState(), SnapshotMutationPolicy.referentialEquality())
    }

    val isValid = remember(formState) {
        formState.email.contains("@") && formState.password.length() >= 6
    }

    Column(modifier = Modifier.padding(16.dp)) {
        OutlinedTextField(
            value = formState.email,
            onValueChange = { formState = formState.copy(email = it) },
            label = { Text("Email") }
        )
        OutlinedTextField(
            value = formState.password,
            onValueChange = { formState = formState.copy(password = it) },
            label = { Text("Password") },
            visualTransformation = PasswordVisualTransformation()
        )
        Button(
            onClick = { onLogin(formState.email, formState.password) },
            enabled = isValid
        ) {
            Text("Mag-login")
        }
    }
}

Sa halimbawang ito, ang mutableStateOf ay ginagamit sa isang custom na data class na LoginState at policy referentialEquality. Ito ay nangangahulugan na ang recomposisyon ay masisimula lamang sa pagtatalaga ng isang bagong instance ng LoginState sa pamamagitan ng copy(). Ang isValid ay kinakalkula batay sa formState at muling kinakalkula lamang kapag ito ay nagbago. Ang pamamaraang ito ay nagbibigay ng malinaw na kontrol sa recomposisyon: bawat field ng form ay nagbabago lamang sa pamamagitan ng paglikha ng bagong kopya.

Mga Madalas Itanong

Ano ang pagkakaiba ng mutableStateOf at StateFlow?

mutableStateOf ay isang lalagyann na tiyak sa Compose na gumagana sa loob ng mga snapshot. Ang StateFlow ay mula sa kotlinx.coroutines.flow na hindi nakatali sa Compose. Ang mutableStateOf ay awtomatikong nagsisimula ng recomposisyon, ang StateFlow ay nangangailangan ng collectAsState(). Para sa UI state sa loob ng Composable, mas gusto ang mutableStateOf.

Maaari bang gamitin ang mutableStateOf sa labas ng mga function na @Composable?

Oo, ang mutableStateOf ay maaaring tawagin sa labas ng Composable function, ngunit hindi ito susubaybayan. Para sa reaktibidad sa UI, kailangang basahin ang State sa loob ng Composable. Maraming ViewModel ang gumagamit ng MutableStateField (isang balot sa ibabaw ng mutableStateOf) para magpadala ng estado sa UI sa pamamagitan ng StateFlow.

Ano ang mangyayari sa sabay na pagbabago ng State mula sa dalawang thread?

Snapshot sistema ay ginagarantiyahan ang pagkakapare-pareho: bawat recomposisyon ay nakakakita ng pare-parehong estado sa sandali ng pagsisimula ng snapshot. Ang mga pagbabago mula sa iba't ibang thread ay inilalapat nang atomiko sa hangganan ng frame, na nag-aalis ng race condition sa pagbasa sa loob ng isang komposisyon.

Paano i-reset ang mutableStateOf sa paunang halaga?

Magtalaga ng bagong halaga: count.value = 0 (o count = 0 sa delegasyon). Kung kailangan ang kumpletong muling paglikha ng State — gumamit ng remember na may susi: remember(key) { mutableStateOf(initial) } — kapag nagbago ang susi, ang State ay malilikha muli.

Nakakaapekto ba ang mutableStateOf sa pagganap sa madalas na pagbabago?

Ang Composer ay gumagamit ng snapshot na naggrupo ng mga pagbabago: kahit na may isandaang pagtatalaga sa isang frame, ang recomposisyon ay isinasagawa lamang nang isang beses. Para sa napakadalas na pag-update (animation), gamitin ang Animatable o animate*AsState — ang mga ito ay na-optimize para sa mga pag-update ng frame.

Buod

  • mutableStateOf ay lumilikha ng napapansing lalagyan ng MutableState na sinusubaybayan ng Compose Runtime
  • Delegasyon sa pamamagitan ng by ay nagpapasimple ng code, ngunit hindi nagbabago ng mekanika ng State
  • Snapshot sistema ay ginagarantiyahan ang pagkakapare-pareho ng pagbasa at pumipigil sa hindi kinakailangang recomposisyon
  • Policy ay tumutukoy kung kailan ang pagbabago ay itinuturing na makabuluhan — structuralEquality, referentialEquality, neverEqual
  • remember ay sapilitan para sa pagpapanatili ng State sa pagitan ng recomposisyon sa loob ng Composable
  • Rekomendasyon: gamitin ang mutableStateOf na may delegasyon para sa UI state at referentialEquality para sa mga data class
  • Iwasan: paggawa ng mutableStateOf nang walang remember — bawat pagtatalaga ay lilikha ng bagong bagay

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.

Pag-usapan ang proyekto

Basahin din