0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【初学者向け】StatefulWidgetとは?

Last updated at Posted at 2025-02-11

StatefulWidgetとはなんでしょうか?

状態を持つWidgetという認識で間違いありませんが、少し大雑把すぎます。私もFlutterを勉強する中でStatefulWidgetの理解に時間をかけてしまっていたので、私自身も含めて初学者向けにStatefulWidgetについて認識を共有しようと思います。

カウンターアプリを例に解説します。

class ProductCard extends StatefulWidget {
  // 外部から渡される値(設定)を定義
  final String productName;
  final int price;
  final Color backgroundColor;

  // コンストラクタで値を受け取る
  const ProductCard({
    super.key,
    required this.productName,
    required this.price,
    this.backgroundColor = Colors.white,
  });

  // Stateクラスを作成(1回だけ実行)
  @override
  State<ProductCard> createState() => _ProductCardState();
}

class _ProductCardState extends State<ProductCard> {
  // 変更される値(状態)を定義
  bool isFavorite = false;

  @override
  Widget build(BuildContext context) {
    // widget.を使ってWidgetクラスの値を参照
    return Card(
      color: widget.backgroundColor,
      child: Column(
        children: [
          Text(widget.productName),
          Text('${widget.price}円'),
          // 状態に基づいて表示を変更
          IconButton(
            icon: Icon(
              isFavorite ? Icons.favorite : Icons.favorite_border
            ),
            onPressed: () {
              setState(() {
                isFavorite = !isFavorite;  // 状態を更新
              });
            },
          ),
        ],
      ),
    );
  }
}

StatefulWidgetには2つのクラスが存在します。

StatefulWidgetクラス

  • 外部から設定を受け取る
    • 例ではproductName、price、backgrounfColorがこれに当たります
    • コンストラクタで値を受け取り、Stateクラス内に適用します
  • createStateを実行しStateクラスを作成
    • 1度だけ実行し、Stateを作成

Stateクラス

  • 状態を持つ値を管理
    • 例ではisFavoriteがこれに当たります
  • build()で画面を構築
  • setStateを実行するとbuild()が再実行され、UIが更新される
    • setStateがなくても値は変更しますが、画面には反映されません

注意点

状態を持つ値、すなわち変数の定義位置に注意してください。

class _ProductCardState extends State<ProductCard> {
  // 本来の状態定義位置

  @override
  Widget build(BuildContext context) {
    // ここで状態を定義してはいけない
    return Card(

build()内で変数を定義すると、setStateが実行されるたびに変数が初期値になってしまいます。
例ではボタンをタップするとisFavoriteが反転(true↔︎false)しますが、定義位置がbuild内にある場合UIが変更されません。
※具体的にはタップした時点では値は変更されていますが(setState実行前)、setStateが実行されると初期値に戻るため結果的にUIに変更が生じません。

まとめ

  • 変更可能な状態(データ)を持つことができる
  • 状態の変更には必ずsetState()を使う
  • UIの更新は自動的に行われる
  • StatefulWidgetとStateクラスの2つで1セット

発展的な使い方

  • 複数の状態を持つWidget
  • 親Widgetからのデータ受け渡し
  • アニメーションの制御
  • フォームの状態管理
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?