State: ano ito, pamamahala ng estado at prinsipyo ng paggana

May-akda: IT Sectr Nai-publish: 2026-07-01 Oras ng pagbabasa: 9 min

State — ang sentral na object ng pamamahala ng data sa Flutter, nauugnay sa StatefulWidget at responsable para sa pag-iimbak ng nababagong impormasyon at pagbuo ng interface. Ayon sa opisyal na dokumentasyon ng Flutter (Flutter.dev, 2026), umiiral ang State sa buong siklo ng buhay ng widget at nakaliligtas sa muling pagtatayo nito, na tinitiyak ang pagkakapare-pareho ng data sa pagitan ng mga update ng UI. Hindi tulad ng widget mismo, maaaring baguhin ng State ang mga field nito at simulan ang muling pagtatayo sa pamamagitan ng pagtawag ng setState.

Mga Pangunahing Punto

  • State — object na nag-iimbak ng nababagong data ng StatefulWidget at namamahala sa muling pagtatayo nito sa pamamagitan ng setState
  • Siklo ng buhay — dumadaan ang State sa initState, didChangeDependencies, build, didUpdateWidget at dispose, bawat yugto na may malinaw na layunin
  • mounted — bandila na nagpapahiwatig na nasa widget tree pa rin ang State at maaaring ligtas na tumawag ng setState
  • widget — referens sa nauugnay na StatefulWidget, naa-access sa pamamagitan ng property ng State para basahin ang mga parameter ng magulang
  • Pag-iisa — isolated ang State mula sa iba pang State; para sa pagpapalitan ng data ginagamit ang InheritedWidget o mga panlabas na tool sa pamamahala ng estado

Ano ang State sa Flutter?

State — ay isang object sa arkitektura ng Flutter na nag-iimbak ng nababagong data ng StatefulWidget at tinutukoy kung paano ipapakita ang data na ito sa interface. Bawat StatefulWidget kapag naka-embed sa tree ay gumagawa ng eksaktong isang State object sa pamamagitan ng createState na pamamaraan. Umiiral ang State nang hiwalay sa widget: kung muling itatayo ng magulang ang StatefulWidget na may bagong mga parameter, nananatili ang State at natatanggap ang na-update na widget sa pamamagitan ng property na widget.

Ayon sa Flutter Architectural Overview (Google, 2026), ang paghihiwalay ng Widget at State ay isang sinadyang desisyon sa arkitektura na nagpapahintulot sa framework na muling gamitin ang mga elemento ng tree. Ang widget (magaan na paglalarawan) ay maaaring gawin at sirain nang maraming beses, ngunit ang State (mabigat na object na may data) ay nananatili sa memorya hangga't ang elemento ay nasa tree. Pinipigilan nito ang pagkawala ng data sa madalas na muling pagtatayo ng mga widget ng magulang.

Ipinapatupad ng State ang interface na StatefulWidget sa pamamagitan ng generik: class _MyState extends State<MyWidget>. Itinatali ng generik ang State sa isang partikular na uri ng StatefulWidget, na nagbibigay ng type-safe na access sa mga field nito sa pamamagitan ng property na widget.

Saan nakatago ang State?

Ang object na State ay nakatago sa StatefulElement — ang intermediate layer sa pagitan ng Widget at RenderObject. Gumagawa ang StatefulElement ng State sa pamamagitan ng createState, iniimbak ang referens dito at ipinapasa ang State bilang may-ari. Ang Element ay sinisira lamang kapag ang widget ay tinanggal mula sa tree — hanggang sa sandaling iyon ay nabubuhay ang State sa memorya.

Siklo ng Buhay ng State

Ang siklo ng buhay ng State ay deterministiko at binubuo ng isang mahigpit na pagkakasunod-sunod ng mga tawag. Ang pag-unawa sa pagkakasunod-sunod na ito ay pundasyon ng tamang paggawa sa mga mapagkukunan at pagpigil sa pagtagas ng memorya.

initState — pagsisimula

initState ay unang tinatawag sa paggawa ng State. Sa pamamaraang ito, sinisimulan ang mga controller, subscription sa mga stream ng data, timer at mga paunang halaga ng field. Ang pagtawag ng super.initState() sa unang linya ay sapilitan. Sa yugto ng initState, ang widget tree ay hindi pa ganap na naka-mount, kaya ang mga pamamaraan tulad ng MediaQuery.of(context) ay maaaring hindi gumana nang tama.

didChangeDependencies

didChangeDependencies ay tinatawag pagkatapos ng initState at sa bawat pagbabago ng mga dependensya ng InheritedWidget. Dito, hindi sa initState, dapat tawagan ang MediaQuery.of(context) o Theme.of(context), dahil sa puntong ito ang tree ay naka-mount na. Ang pamamaraang ito ay tinatawag din kung ang widget ay inilipat sa ibang konteksto kung saan ang InheritedWidget ay nagbibigay ng iba't ibang halaga.

build — pagbuo ng UI

build — ang pangunahing pamamaraan ng State na nagbabalik ng widget tree. Tinatawag pagkatapos ng initState, pagkatapos ng didChangeDependencies at pagkatapos ng bawat setState. Ang build na pamamaraan ay hindi dapat magkaroon ng mga side effect — inilalarawan lamang nito ang interface batay sa kasalukuyang halaga ng mga field ng State.

didUpdateWidget

didUpdateWidget ay tinatawag kapag muling itinatayo ng magulang ang StatefulWidget na may bagong mga parameter. Ang State ay nakakakuha ng access sa lumang widget sa pamamagitan ng oldWidget at maaaring ihambing ito sa bago. Kung nagbago ang mga parameter, maaaring i-update ang estado, mag-load ng bagong data o i-restart ang animasyon.

dispose — pagpapalaya ng mga mapagkukunan

dispose — ang pangwakas na pamamaraan kung saan pinalaya ang lahat ng mga mapagkukunan: controllers, subscription, timer. Pagkatapos ng dispose, ang State ay minarkahan bilang patay: mounted ay nagbabalik ng false, ang pagtawag ng setState ay nagtatapon ng exception. Ang pagtawag ng super.dispose() sa huling linya ng pamamaraan ay sapilitan.

PamamaraanKailan tinatawagSapilitang super
initStateSa paggawa ng StateOo, sa unang linya
didChangeDependenciesPagkatapos ng initState at sa pagbabago ng InheritedWidgetOo
buildPagkatapos ng initState, didChangeDependencies, setStateHindi
didUpdateWidgetSa bagong widget mula sa magulangOo
setStateSa tawag ng developerHindi
disposeSa pagtanggal mula sa treeOo, sa huling linya

Paano Gumagana ang State?

Ang mekanismo ng paggana ng State ay batay sa tatlong pangunahing prinsipyo: asosasyon sa Element, reaktiviti sa pamamagitan ng setState at access sa magulang sa pamamagitan ng widget na property. Kapag itinatayo ng Flutter ang element tree at nakatagpo ng StatefulElement, tinatawag nito ang createState ng nauugnay na widget. Ang nilikha na State ay iniimbak sa elemento at umiiral hanggang sa tanggalin ang elemento.

Sa pagtawag ng setState, minamarkahan ng State ang sarili bilang “dirty” at iniiskedyul ang muling pagtatayo para sa susunod na frame. Mahalaga: hindi agad tinatawag ng setState ang build — itinatala lamang nito ang pangangailangan para sa muling pagtatayo. Kinokolekta ng Flutter ang lahat ng maruruming elemento sa kasalukuyang frame at itinatayo ang mga ito nang batch, na nag-o-optimize ng pagganap. Pagkatapos ng build na tawag, bumabalik ang State sa “clean” na estado.

Ang property na widget ay nagpapahintulot sa State na basahin ang mga parameter na ipinasa sa constructor ng StatefulWidget. Dahil ang StatefulWidget ay hindi nababago (tulad ng StatelessWidget), ang mga field nito ay hindi nagbabago — sa pagbabago ng mga parameter, ang magulang ay gumagawa ng bagong widget, at natatanggap ito ng State sa pamamagitan ng didUpdateWidget. Ginagarantiyahan nito na ang State ay palaging gumagana sa napapanahong data ng magulang.

Mga Halimbawa ng Kodigo sa Dart

Pangunahing halimbawa ng State na may field na binabago ng timer. Nagpapakita ng initState, setState at dispose:

dart
class _TimerWidgetState extends State<TimerWidget> {
  int _seconds = 0;
  Timer? _timer;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(
      const Duration(seconds: 1),
      (_) => setState(() => _seconds++),
    );
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text('$_seconds segundo ang lumipas');
  }
}

Halimbawa ng paggamit ng property na widget para sa access sa mga parameter ng magulang at reaksyon sa kanilang mga pagbabago sa pamamagitan ng didUpdateWidget:

dart
class _GreetingState extends State<GreetingWidget> {
  String _displayName = '';

  @override
  void initState() {
    super.initState();
    _displayName = _formatName(widget.name);
  }

  @override
  void didUpdateWidget(GreetingWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.name != oldWidget.name) {
      setState(() {
        _displayName = _formatName(widget.name);
      });
    }
  }

  String _formatName(String name) => name.trim().isEmpty ? 'Guest' : name;

  @override
  Widget build(BuildContext context) {
    return Text('Kumusta, $_displayName!');
  }
}

Sa pangalawang halimbawa, sinusubaybayan ng State ang pagbabago ng input parameter na name at reformat ang display lamang sa aktwal na pagbabago. Kung walang pagsusuri ng widget.name != oldWidget.name, ang pamamaraan ay tatawagin sa bawat muling pagtatayo ng magulang, kahit na hindi nagbago ang pangalan — ito ay dagdag na trabaho para sa framework.

State vs StatefulWidget

State at StatefulWidget ay dalawang magkaibang klase sa arkitektura ng Flutter na may magkaibang mga tungkulin. Ang StatefulWidget — ay isang magaan na hindi nababagong pambalot na naglalarawan ng configuration ng widget at gumagawa ng State. Ang State — ay isang mabigat na object na nag-iimbak ng nababagong data, namamahala ng mga subscription at bumubuo ng UI. Ang paghihiwalay na ito ay nagpapahintulot sa Flutter na sirain at lumikha ng mga widget nang hindi nawawala ang estado.

Lahat ng field ng StatefulWidget ay dapat final at itakda sa constructor — hindi sila nagbabago pagkatapos ng paggawa. Ang State, sa kabaligtaran, ay maaaring baguhin ang mga field nito anumang oras, ngunit ang lahat ng pagbabago ay dapat unahan ng pagtawag ng setState, upang malaman ng Flutter ang pangangailangan para sa muling pagtatayo. Ito ang pangunahing pagkakaiba: ang StatefulWidget ay “kung ano ang ipapakita”, ang State — “kung paano ipakita at kung anong data ang gagamitin”.

Ayon sa Flutter source code analysis (Flutter SDK, 2026), ang StatefulWidget ay naglalaman lamang ng isang sapilitang field — createState, samantalang ang State ay may access sa BuildContext, maaaring mag-subscribe sa mga stream, mamahala ng mga animasyon at controllers. Inirerekomenda na panatilihing simple ang StatefulWidget hangga't maaari, ilipat ang lahat ng lohika sa State.

Bakit hindi maaaring maging State ang StatefulWidget?

Paghihiwalay ng Widget at State — isang desisyon sa arkitektura na ginagarantiyahan ang hindi pagbabago ng configuration. Kung ang StatefulWidget mismo ay nag-imbak ng estado, sa bawat muling pagtatayo ng magulang ay mawawala ang estado. Sa pamamagitan ng paghiwalay ng estado sa isang hiwalay na object, ginagarantiyahan ng Flutter na ang data ay nakaliligtas sa muling pagtatayo, at ang mga widget ay nananatiling magaan at maihahambing.

Pamamahala ng Estado sa Pagitan ng mga Widget

Ang object na State ay isolated — wala itong direktang access sa State ng iba pang mga widget. Para sa pagpapalitan ng data sa pagitan ng mga widget ginagamit ang InheritedWidget o mga panlabas na tool sa pamamahala ng estado: Provider, Riverpod, Bloc, Redux. Bawat approach ay nilulutas ang problema sa sarili nitong paraan: ang InheritedWidget ay gumagana sa pamamagitan ng widget tree, ang Provider — sa pamamagitan ng DI container, ang Bloc — sa pamamagitan ng mga stream ng kaganapan.

Ang pagpili ng tool ay depende sa laki ng proyekto. Para sa maliit na aplikasyon, sapat na ang InheritedWidget at lokal na State. Para sa katamtaman at malaking proyekto, inirerekomenda ang Riverpod o Bloc — nagbibigay sila ng testability, predictability at paghihiwalay ng lohika mula sa UI. Ang State sa kasong ito ay ginagamit lamang para sa lokal na data ng widget (focus, scroll, animation).

Ayon sa Flutter Community Survey 2025 (Flutter Foundation, Disyembre 2025), ang Riverpod ang pinakasikat na solusyon para sa pamamahala ng estado sa mga bagong proyekto (38%), sinundan ng Bloc (31%) at Provider (22%). Lahat ng tatlong tool ay compatible sa State at hindi nangangailangan ng pag-abandona sa standard na siklo ng buhay.

Lokal vs global na estado

  • Lokal — sa State ng partikular na widget (posisyon ng scroll, estado ng focus)
  • Global — sa panlabas na imbakan (data ng user, mga setting, cache)
  • Patakaran: kung ang data ay ginagamit lamang ng isang widget — itago sa State
  • Kung ang data ay ginagamit ng 2+ widget — ilipat sa Riverpod/Bloc/Provider

Mga Karaniwang Pagkakamali

Unang pagkakamali — kalimutang suriin ang mounted bago ang setState sa isang asynchronous na callback. Kapag ang widget ay tinanggal mula sa tree (hal., umalis ang user sa screen), ngunit ang asynchronous na operasyon (HTTP request) ay tumatakbo pa, pagkatapos ng pagkumpleto nito ay patay na ang State. Ang pagtawag ng setState sa patay na State ay nagtatapon ng exception. Ang pagsusuri na if (mounted) setState(...) ay lumulutas ng problema.

Pangalawang pagkakamali — pagsisimula ng mga dependensya ng InheritedWidget sa initState sa halip na didChangeDependencies. Sa initState ang konteksto ay hindi pa naka-mount, kaya ang MediaQuery.of(context) ay magtatapon ng exception. Lahat ng dependensya ng InheritedWidget ay dapat i-configure sa didChangeDependencies o sa build.

Pangatlong pagkakamali — pag-mutate ng mga field nang hindi tinatawag ang setState. Kung babaguhin ng developer ang field ng State nang walang setState, hindi malalaman ng Flutter ang pagbabago at hindi mag-a-update ang UI. Halimbawa: _list.add(item) nang walang kasunod na setState((){}) ay magbabago sa listahan, ngunit ang screen ay mananatiling pareho.

Pagsusuri ng mounted bago ang setState

Pattern ng kaligtasan para sa asynchronous na mga operasyon sa State:

dart
Future<void> _fetchData() async {
  final data = await ApiService.fetch();
  if (mounted) {
    setState(() => _data = data);
  }
}

Ang pagsusuri ng mounted ay ginagarantiyahan na ang setState ay tinatawag lamang para sa buhay na State, na pumipigil sa exception na “setState called after dispose”.

Mga Madalas Itanong

Ano ang pagkakaiba ng State sa StatefulWidget?

StatefulWidget — hindi nababagong configuration ng widget, at State — nababagong object na nag-iimbak ng data at namamahala ng siklo ng buhay. Ang widget ay maaaring muling likhain, ang State — hindi. Gumagawa ang StatefulWidget ng State sa pamamagitan ng createState.

Ilang State object ang nagagawa para sa isang StatefulWidget?

Eksaktong isa. Ang createState na pamamaraan ay tinatawag nang isang beses sa unang pag-embed ng StatefulWidget sa tree. Kahit na muling itayo ng magulang nang maraming beses, ang State object ay nananatiling pareho, hanggang sa magbago ang uri o Key ng widget.

Ano ang mounted sa State?

mounted — isang boolean na bandila na nagpapakita kung ang State ay nasa widget tree. Pagkatapos tumawag ng dispose, nagiging false ang mounted. Ginagamit para sa pagsusuri bago ang setState sa asynchronous na mga callback upang maiwasan ang exception.

Maaari bang gamitin ang State nang walang StatefulWidget?

Hindi. Ang State ay palaging nakatali sa isang partikular na StatefulWidget sa pamamagitan ng generik: State<T extends StatefulWidget>. Ang direktang paggawa ng State, nang walang asosasyon sa widget, ay imposible sa arkitektura.

Ano ang mangyayari kung tatawagin ang setState sa dispose?

Magtatapon ng exception: “setState called after dispose”. Pagkatapos tumawag ng dispose, ang State ay itinuturing na patay at anumang pagtatangka na muling itayo ang UI sa pamamagitan ng setState ay ipinagbabawal. Solusyon — suriin ang mounted bago ang bawat setState.

Buod

  • State — object ng pamamahala ng data ng StatefulWidget, nag-iimbak ng nababagong field at nagsisimula ng muling pagtatayo ng UI sa pamamagitan ng setState
  • Siklo ng buhay ay may kasamang sapilitang pamamaraan na initState, didChangeDependencies, build, didUpdateWidget at dispose, bawat isa ay may kanya-kanyang layunin
  • mounted — kritikal na bandila ng kaligtasan na pumipigil sa pagtawag ng setState pagkatapos tanggalin ang widget mula sa tree
  • widget — property ng State para sa access sa mga parameter ng nauugnay na StatefulWidget, na-update sa pamamagitan ng didUpdateWidget
  • Pag-iisa — ang State ay walang access sa iba pang State; ang interaksyon sa pagitan ng widget ay naisasagawa sa pamamagitan ng InheritedWidget o panlabas na tool
  • setState — hindi agad tinatawag ang build, minamarkahan lamang ang State bilang dirty para sa muling pagtatayo sa susunod na frame
  • Patakaran — gamitin ang State para sa lokal na data ng widget; ilipat ang global na estado sa panlabas na layer (Riverpod, Bloc)

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