# 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。
**Q:如何做到 `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?為什麼?***