setState 与 StreamProvider
setState vs StreamProvider
我是Flutter新手,有一个基本的理解问题:
我构建了一个 google_maps 小部件,用于获取用户的位置,还想在 TextWidget 中显示当前位置。
所以我在 initState 中调用一个函数来查询地理定位器包的流:
class _SimpleMapState extends State<SimpleMap> {
Position userPosStreamOutput;
void initPos() async {
userPosStream = geoService.getStreamLocation();
userPosStream.listen((event) {
print('event:$event');
setState(() {
userPosStreamOutput = event;
});
});
setState(() {});
}
@override
void initState() {
initPos();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold( //(very simplified)
body: Text(userPosStreamOutput.toString()),
这很好用。但是改用 Streamprovider 有意义吗?为什么?
谢谢
约尔格
使用 StreamProvider 的一个好处是优化了重新渲染的过程。由于调用 setState 来更新 userPosStreamOutput 值,每次流产生事件时都会调用构建方法。
使用 StreamProvider,您可以应用与初始化流相同的逻辑,但是随后,您将使用一个 Consumer,它将侦听传入的新事件并向子 widget 提供更新的数据,而不会触发其他构建方法调用。
使用这种方法,构建方法将被调用一次,而且在我看来它也使代码更具可读性。
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamProvider(
create: (_) => geoService.getStreamLocation(),
initialData: null,
child: Consumer<Position>(
builder: (context, userPosStreamOutput, _) {
return Text(userPosStreamOutput.toString());
},
),
),
);
}
我是Flutter新手,有一个基本的理解问题:
我构建了一个 google_maps 小部件,用于获取用户的位置,还想在 TextWidget 中显示当前位置。
所以我在 initState 中调用一个函数来查询地理定位器包的流:
class _SimpleMapState extends State<SimpleMap> {
Position userPosStreamOutput;
void initPos() async {
userPosStream = geoService.getStreamLocation();
userPosStream.listen((event) {
print('event:$event');
setState(() {
userPosStreamOutput = event;
});
});
setState(() {});
}
@override
void initState() {
initPos();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold( //(very simplified)
body: Text(userPosStreamOutput.toString()),
这很好用。但是改用 Streamprovider 有意义吗?为什么?
谢谢 约尔格
使用 StreamProvider 的一个好处是优化了重新渲染的过程。由于调用 setState 来更新 userPosStreamOutput 值,每次流产生事件时都会调用构建方法。
使用 StreamProvider,您可以应用与初始化流相同的逻辑,但是随后,您将使用一个 Consumer,它将侦听传入的新事件并向子 widget 提供更新的数据,而不会触发其他构建方法调用。
使用这种方法,构建方法将被调用一次,而且在我看来它也使代码更具可读性。
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamProvider(
create: (_) => geoService.getStreamLocation(),
initialData: null,
child: Consumer<Position>(
builder: (context, userPosStreamOutput, _) {
return Text(userPosStreamOutput.toString());
},
),
),
);
}