我很难理解为什么有状态小部件在重建后没有更新状态。我有一个有状态的小部件,它负责每秒减少一个计数器,因此它接收到一个初始值,然后将该初始值传递给State并开始对其进行递减。
还有一个按钮,当按下该按钮时,会将一个事件发送到我的集团,该集团使用新的初始值重建有状态的小部件,事实是,它确实发送并更新了初始值,但是计数器继续递减旧值,并且我不知道为什么。下面是代码示例:
小部件
void main() => runApp(
BlocProvider(
create: (context) => TBloc(),
child: MaterialApp(
home: Scaffold(
body: BlocBuilder<TBloc, BState>(
builder: (context, state) {
if (state is BState) {
return Column(
children: [
Counter(state.value),
FlatButton(
child: Text("tap"),
onPressed: () =>
BlocProvider.of<TBloc>(context).add(BEvent(200)),
),
],
);
}
return Container();
},
),
),
),
),
);
class Counter extends StatefulWidget {
final int initialValue;
Counter(this.initialValue);
@override
CounterState createState() => CounterState(this.initialValue);
}
class CounterState extends State<Counter> {
Timer timer;
int value;
CounterState(this.value);
@override
void initState() {
super.initState();
timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() => --value);
});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("Value: $value"),
Text("Initial: ${widget.initialValue}")
],
);
}
}
集团
class TBloc extends Bloc<BEvent, BState> {
@override
BState get initialState => BState(100);
@override
Stream<BState> mapEventToState(BEvent event) async* {
yield BState(event.value);
}
}
class BEvent extends Equatable {
final int value;
BEvent(this.value);
@override
List<Object> get props => [value];
}
class BState extends Equatable {
final int value;
BState(this.value);
@override
List<Object> get props => [value];
}
谢谢。
答案 0 :(得分:1)
这是因为您仅在Timer
的{{1}}上设置Counter
,每个小部件生命周期都将其设置为 only 。
基本上,第一次构建initState
时,它将调用Counter
,只要它保留在该小部件树中,就只会initState()
和/或didUpdateWidget()
被调用以更新那个小部件(例如,当您使用新参数重建时,就像您正在做的那样)。
didChangeDependencies()
方法也会发生同样的情况,这与dispose()
仅被称为一次的方法相反,但是这次是从树中删除窗口小部件。
此外,您在此处使用错误的状态。您不需要将参数传递给状态本身(就像您所做的那样:
initState()
但是,相反,您可以通过调用 CounterState createState() => CounterState(this.initialValue);
从该窗口小部件访问所有参数。
因此,基本上,您要做的就是基于新更新来更新widget.initialValue
小部件,如下所示:
Counter