---
# System prepended metadata

title: Flutter State Management

---

# Flutter State Management

### StatefulWidget vs StatelessWidget

* **StatelessWidget**: 無狀態 widget，在 `build` 函數返回一個 widget，建構一次後就不會再呼叫此函數，需要參數時放在建構子內，用 class level property 存取後可在 `build` 函數內使用。

* **StatefulWidget**: 有狀態 widget，在 `createState` 返回一個包含一個 widget 的 State，需要參數時放在建構子內，用 class level property 存取後可在 `State` 類別內使用。

* **State**: 一個抽象類別並只接收一個 `StatefulWidget` 參數，在 `build` 函數返回一個 widget，需要參數時可透過 `widget.XXXproperty` 取得 `StatefulWidget` 內的屬性，資料更動需要刷新界面時呼叫 `setState` 就會透過 `build` 函數重新渲染。

### Widget 之間如何傳遞資料
```
ParentWidget extends StatelessWidget(
  children:[
    AWidget(),
    BWidget(),
    ...
  ]
)

AWidget extends StatefulWidget(

  int valueA = 0;
 
  @override
  State<AWidget> createState() => _AWidgetState();
)

class _AWidgetState extends State<AWidget> {
    
  @override
  Widget build(BuildContext context) {
    return ...(
      Text('valueA = $valueA');
      ...
      onPress() {
       setState(() {
          valueA ++;
       });
      }
    )
  }
}

BWidget extends StatefulWidget(

  int valueB = 0;
 
  @override
  State<BWidget> createState() => _BWidgetState();
)

class _BWidgetState extends State<BWidget> {
    
  @override
  Widget build(BuildContext context) {
    return ...(
      Text('valueB = $valueB');
      ...
      onPress() {
       setState(() {
          valueB ++;
       });
      }
    )
  }
}
```

以上是 `AWidget` 顯示 valueA，`BWidget` 顯示 valueB，並各自管理 state。

**Ｑ：如何做到 `AWidget` 顯示 valueA + valueB，`BWidget` 也顯示 valueA + valueB?**

**A：** 把需要共用的 value 存在父 widget，經由父 widget 將參數傳遞下去。
子 widget 在需要 value 改變時透過 callback 回到父 widget 改變 value 並呼叫 `setState` 重新渲染 UI。

```
ParentWidget extends StatefulWidget(
  
  @override
  State<ParentWidget> createState() => _ParentWidgetState();
)

class _ParentWidgetState extends State<ParentWidget> {

  int valueA = 0;
  int valueB = 0;
    
  @override
  Widget build(BuildContext context) {
    return children:[
      AWidget(valueA, valueB,
        addValue(){
         setState(() {
           valueA++;
         });
        }
      ),
      BWidget(valueA, valueB,
        addValue(){
         setState(() {
           valueB++;
         });
        }
      ),
      ...
    ]
  }
}

AWidget extends StatelessWidget(
  final Function() addValue;

  const AWidget({super.key, required this.onSelect});

  @override
  Widget build(BuildContext context) {
    return ...(
      Text('valueA = $valueA, valueB = $valueB');
      ...
      onPress() {
        addValue();
      }
    )
  }
)

BWidget extends StatelessWidget(
  final Function() addValue;

  const BWidget({super.key, required this.onSelect});

  @override
  Widget build(BuildContext context) {
    return ...(
      Text('valueA = $valueA, valueB = $valueB');
      ...
      onPress() {
        addValue();
      }
    )
  }
)
```

以上是 `AWidget` 顯示 valueA + valueB，`BWidget` 顯示 valueA + valueB，並可以交互影響。

***注意前後寫法各自 widget 繼承的是 StatefulWidget 或是 StatelessWidget？為什麼？***