setState 与 StreamProvider

问题描述

我是 Flutter 新手,我有一个基本的理解问题:

我构建了一个 google_maps 小部件,我可以在其中获取用户的位置,并且还想在 TextWidget 中显示当前位置。

所以我在 initState 中调用一个函数查询 geolocator 包的流:

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 值,因此每次流产生事件时都会调用 build 方法。

使用 StreamProvider,您可以应用与初始化流相同的逻辑,但随后您将使用 Consumer,它会侦听传入的新事件并向子小部件提供更新的数据,而不会触发其他构建方法调用。

使用这种方法,构建方法将被调用一次,并且在我看来它也使代码更具可读性。

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: StreamProvider(
      create: (_) => geoService.getStreamLocation(),initialData: null,child: Consumer<Position>(
        builder: (context,userPosStreamOutput,_) {
          return Text(userPosStreamOutput.toString());
        },),);
}