StatefulWidgetは、画面内で変わる値を持つWidgetです。ボタンを押すと数字が増える、読み込み中から完了に変わる、入力内容に応じて表示を変える、といった場面で使います。
この記事の結論
StatefulWidgetはWidget本体とStateクラスの2つで構成します。変化する値はState側に置き、値を変えたらsetStateで再描画します。
StatefulWidgetの最小構成
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int count = 0;
@override
Widget build(BuildContext context) {
return Text("count: $count");
}
}
ボタンで状態を変える
値を変更しただけでは画面は更新されません。setStateの中で値を変更すると、Flutterが再度buildを呼びます。
ElevatedButton(
onPressed: () {
setState(() {
count++;
});
},
child: const Text("増やす"),
)
完成形の小さなカウンター
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int count = 0;
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("count: $count"),
ElevatedButton(
onPressed: () => setState(() => count++),
child: const Text("増やす"),
),
],
);
}
}
StatelessWidgetとの使い分け
- 表示内容が外から渡されるだけならStatelessWidget
- Widget内で値が変わるならStatefulWidget
- アプリ全体で共有する状態はProviderやRiverpodも検討
- 小さな画面内の状態ならまずStatefulWidgetで十分
実装後に確認すること
- ボタンを押して値が変わるか
- 変化する値をState側に置いているか
- setState内で状態を変更しているか
- 複雑な状態を1つのWidgetに詰め込みすぎていないか
よくあるつまずき
- StatefulWidget本体に変化する値を置く
- 値を変えたのにsetStateを呼ばない
- build内で重い処理を実行する
- 小さな状態管理にいきなり大きな設計を持ち込む
次に読む記事
- Flutter setStateの使い方|画面を更新する基本と注意点 — FlutterのsetStateを初心者向けに解説します。値を変更して画面を更新する流れ、よくある書き方、非同期処理後の注意点を整理します。
- Flutter Containerの使い方|余白・背景色・サイズ指定の基本 — FlutterのContainerを初心者向けに解説します。サイズ、余白、背景色、角丸、中央配置など、画面レイアウトでよく使う基本を整理します。
- Dart async awaitの使い方|Futureを順番に待つ基本を初心者向けに解説 — Dartのasync/awaitを初心者向けに解説します。Futureとthenの関係、awaitで待つ書き方、try-catch、Future.wait、Flutterでローディング表示につなげる考え方を整理します。
まとめ
StatefulWidgetはFlutterで状態を持つ画面を作る基本です。Stateクラスに値を置き、setStateで変更し、buildが再実行される流れを理解しましょう。