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 — 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.
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.
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 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 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 — 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 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 — 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.
| Pamamaraan | Kailan tinatawag | Sapilitang super |
|---|---|---|
| initState | Sa paggawa ng State | Oo, sa unang linya |
| didChangeDependencies | Pagkatapos ng initState at sa pagbabago ng InheritedWidget | Oo |
| build | Pagkatapos ng initState, didChangeDependencies, setState | Hindi |
| didUpdateWidget | Sa bagong widget mula sa magulang | Oo |
| setState | Sa tawag ng developer | Hindi |
| dispose | Sa pagtanggal mula sa tree | Oo, sa huling linya |
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.
Pangunahing halimbawa ng State na may field na binabago ng timer. Nagpapakita ng initState, setState at dispose:
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:
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 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.
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.
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.
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.
Pattern ng kaligtasan para sa asynchronous na mga operasyon sa State:
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
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.
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.
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.
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.
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
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