StreamProvider未更新状态 [英] StreamProvider not updating state

查看:148
本文介绍了StreamProvider未更新状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 StreamProvider (来自很棒的软件包),但是我一直在努力使特定的流工作。

I am trying to use a StreamProvider (from this awesome package), but I've been struggling to get a particular stream to work.

我创建了一个 StreamController ,用于将数据添加到其 Stream 通过其接收器。所有这些似乎都工作正常。但是,当将此 Stream StreamProvider 一起使用时,小部件树不会反映流。但是,使用 StreamBuilder 可以正常工作。

I create a StreamController which I use to add data to its Stream via its Sink. All of this seems to be working fine. But when using this Stream with a StreamProvider, the widget tree does not reflect the changes of the Stream. It does however work fine using a StreamBuilder.

使用 StreamProvider 的代码:

class TestPage extends StatelessWidget {
  final Mockup exchange = ExchangeApi.mockup;

  @override
  Widget build(BuildContext context) {
    return StreamProvider<List<Data>>(
      builder: (BuildContext context) => Wrapper.mockup.stream,
      initialData: null,
      catchError: (BuildContext context, e) {
        print("Error: $e");
        return null;
      },
      child: TestPageBody(),
    );
  }
}

class TestPageBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    List<Data> dataList = Provider.of<List<Data>>(context);
    return ListView.builder(
      itemCount: dataList?.length ?? 0,
      itemBuilder: (BuildContext context, int index) {
        return Text(dataList[index].name);
      },
    );
  }
}

我一直在寻找为什么这行不通,但是尚未找到答案。但是我确实找到了一些东西:

I have been searching why this does not work, but haven't found an answer yet. But here are some things I did find:


  • 使用Flutter Desktop Embedding,当窗口调整大小时,UI确实反映了流中的变化(从而迫使重建)。使用热刷新时,会看到相同的效果。

  • 流中不断添加新数据,我通过调试并简单地打印出数据来测试这一点

任何帮助将不胜感激!

推荐答案

大多数人的默认行为提供程序(不包括 ChangeNotifierProvider )将假定传递的值是不可变的。

The default behavior of most providers (excluding ChangeNotifierProvider) is to assume that the values passed are immutable.

因此,如果您的流发出

有两种解决方案:


  • 使流发出的值不可变,这样执行 previousValue == newValue 即可正常工作。

覆盖 updateShouldNotify 以在值不变时不过滤值。

override updateShouldNotify to not filter values if they didn't change.

一个简单的 updateShouldNotify:(_,__)=>

A simple updateShouldNotify: (_, __) => true will do.

这可以通过在将对象发送到 streamController.add(value)<之前复制对象来完成。 / code>:

This can be done by making a copy of your object before sending it to streamController.add(value):

List<T> value;
streamController.add(List.from(value));

第二个(可选)步骤是覆盖 updateShouldNotify (或您对象上的 operator == )通知提供者该值没有更改。

A second (optional) step is to override updateShouldNotify (or operator== on your object) to notify the provider that the value didn't change.

使用列表,可以使用 collection / collection.dart中的 ListEquality 完成此操作

With List, this can be done using ListEquality from collection/collection.dart:

import 'package:provider/provider.dart';
import 'package:collection/collection.dart';

StreamProvider<List<int>>(
  builder: (_) => stream,
  updateShouldNotify: const ListEquality<int>().equals,
);

这篇关于StreamProvider未更新状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆