作为类的状态是不是需要 SatefulWidget?
Posted
技术标签:
【中文标题】作为类的状态是不是需要 SatefulWidget?【英文标题】:Does state as class requires SatefulWidget?作为类的状态是否需要 SatefulWidget? 【发布时间】:2019-12-24 13:44:21 【问题描述】:我正在尝试学习 Flutter 中的 bloc 模式并使用 bloc
框架创建一个示例应用程序。该应用程序是一个计数器,在计数器文本字段下方有两个按钮。在点击True
和False
按钮后,当前我只是分别递增和递减计数器。
我注意到的是,如果我在实现Bloc
模式时使用类作为状态,那么我必须编写StatefulWidget
。相反,如果我只使用int
,那么即使使用StatelessWidget
也可以正常工作。
所以,在实现相同的示例时,它让我感到困惑,使用类作为状态,原始数据类型作为状态。
这是我的代码 CounterBloc
代码,状态定义为类 CounterState
enum CounterEvent Increment, Decrement
class CounterBloc extends Bloc<CounterEvent, CounterState>
CounterState counterState = new CounterState(counter: 0);
@override
// TODO: implement initialState
CounterState get initialState => counterState;
@override
Stream<CounterState> mapEventToState(CounterEvent event) async*
// TODO: implement mapEventToState
switch (event)
case CounterEvent.Decrement:
counterState.decrementCounter();
yield counterState;
break;
case CounterEvent.Increment:
counterState.incrementCounter();
yield counterState;
break;
我的CounterState
定义如下
class CounterState
int counter = 0;
CounterState(this.counter);
void incrementCounter()
counter++;
void decrementCounter()
counter--;
这就是我在按下按钮时调度事件的方式
onPressed: ()
setState(()
counterBloc.dispatch(CounterEvent.Increment);
);
与StatefulWidget
内的UI绑定
BlocBuilder<CounterBloc, CounterState>(builder: (context, snapshot)
.....
child: Text(
snapshot.counter.toString(),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25.0,
color: Colors.white,
),
),
.....
);
现在如果我使用int
作为状态,那么它在StatelessWidget
中工作正常。
这是CounterBloc
,状态为整数
enum CounterEvent Increment, Decrement
class CounterBloc extends Bloc<CounterEvent, int>
@override
// TODO: implement initialState
int get initialState => 0;
@override
Stream<int> mapEventToState(CounterEvent event) async*
// TODO: implement mapEventToState
switch (event)
case CounterEvent.Decrement:
yield currentState -1;;
break;
case CounterEvent.Increment:
yield currentState +1;;
break;
更新
enum CounterEvent Increment, Decrement
class CounterBloc extends Bloc<CounterEvent, CounterState>
@override
// TODO: implement initialState
CounterState get initialState => CounterState(counter: 0);
@override
Stream<CounterState> mapEventToState(CounterEvent event) async*
// TODO: implement mapEventToState
switch (event)
case CounterEvent.Decrement:
CounterState counterState = CounterState(counter: currentState.counter);
counterState.decrementCounter();
yield counterState;
break;
case CounterEvent.Increment:
CounterState counterState = CounterState(counter: currentState.counter);
counterState.incrementCounter();
yield counterState;
break;
在@Rémi Rousselet 的评论的帮助下解决了这个问题。现在我每次都在传递新状态
【问题讨论】:
【参考方案1】:问题不在于它是否是一个类,而在于不变性。
使用bloc
,您的状态必须是不可变的。您不应该修改之前的状态,而是创建一个新的修改状态。
【讨论】:
以上是关于作为类的状态是不是需要 SatefulWidget?的主要内容,如果未能解决你的问题,请参考以下文章