gpt4 book ai didi

flutter - BLOC 状态更改后有状态小部件未重建

转载 作者:行者123 更新时间:2023-12-04 10:50:25 26 4
gpt4 key购买 nike

我很难理解为什么我的有状态小部件在重建后没有更新状态。我有一个有状态的小部件,负责每秒递减一个计数器,因此它接收一个初始值,我将此初始值传递给 State 并开始递减它。

它还有一个按钮,当按下它时向我的 bloc 发送一个事件,它用一个新的初始值重建有状态的小部件,事实是,它确实发送并更新了初始值,但计数器继续递减旧值,我没有线索为什么。这是代码的示例:

小工具

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];
}

先感谢您。

最佳答案

那是因为您只设置了 Timer在您的 CounterinitState每个小部件生命周期仅调用一次。

基本上,当您的 Counter第一次构建时,它会调用 initState()只要它留在那个小部件树中,只有 didUpdateWidget()和/或 didChangeDependencies()将被调用以更新该小部件(例如,当使用新参数重建时,就像您正在做的那样)。
dispose() 也是如此方法,与 initState() 相反只调用一次,但这次是在从树中删除小部件时。

此外,您在这里以错误的方式使用状态。您不需要将参数传递给状态本身(就像您所做的那样:

 CounterState createState() => CounterState(this.initialValue);

但是,您可以通过调用以下方法访问该小部件的所有参数: widget.initialValue .

综上所述,基本上,您要做的是更新您的 Counter基于新更新的小部件,如下所示:
class Counter extends StatefulWidget {
final int initialValue;

Counter(this.initialValue);

@override
CounterState createState() => CounterState();
}

class CounterState extends State<Counter> {
Timer timer;
int value;

void _setTimer() {
value = widget.initialValue;
timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() => --value);
});
}

@override
void initState() {
super.initState();
_setTimer();
}

@override
void didUpdateWidget(Counter oldWidget) {
super.didUpdateWidget(oldWidget);
if(oldWidget.initialValue != widget.initialValue) {
_setTimer();
}
}

@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("Value: $value"),
Text("Initial: ${widget.initialValue}")
],
);
}
}

关于flutter - BLOC 状态更改后有状态小部件未重建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59507162/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com