【问题标题】:using Equatable class with flutter_bloc使用带有flutter_bloc的Equatable类
【发布时间】:2021-01-26 16:46:18
【问题描述】:

为什么当我们需要使用 Flutter_bloc 的 Equatable 类时? ,还有道具呢,我们需要什么?这是在颤动中以 bloc 模式创建状态的示例代码,我需要一个详细的答案。提前谢谢你

abstract class LoginStates extends Equatable{}

class LoginInitialState extends LoginStates{
  @override
  List<Object> get props => [];

}

【问题讨论】:

    标签: flutter flutter-bloc equatable


    【解决方案1】:

    为了比较数据,我们需要Equatable。它在内部覆盖==hashCode,从而节省了大量样板代码。在Bloc 中,我们必须将Equatable 扩展为States and Events 类才能使用此功能。

     abstract class LoginStates extends Equatable{}
    

    因此,这意味着LoginStates 不会进行重复调用,并且如果出现相同的状态,也不会重建小部件。

    定义状态:

    class LoginInitialState extends LoginStates {}
    

    用道具定义状态:

    props 当我们希望 State 与 props List 中声明的值进行比较时声明

    class LoginData extends LoginStates {
      final bool status;
      final String userName;
      const LoginData({this.status, this.userName});
      @override
      List<Object> get props => [this.status, this.userName];
    }
    

    如果我们从列表中删除用户名并保留类似[this.status] 的列表,那么State 将只考虑status 字段,避免username 字段。这就是我们使用 props 来处理状态变化的原因。

    块流使用:

    当我们扩展 State with Equatable 时,它将旧状态数据与新状态数据进行比较。作为一个例子,让我们看看下面的例子,这里 LoginData 将只构建一个小部件,这将避免第二次调用,因为它是重复的。

    @override
    Stream<LoginStates> mapEventToState(MyEvent event) async* {
      yield LoginData(true, 'Hello User');
      yield LoginData(true, 'Hello User'); // This will be avoided
    }
    

    详细博客:https://medium.com/flutterworld/flutter-equatable-its-use-inside-bloc-7d14f3b5479b

    【讨论】:

      【解决方案2】:

      我们正在使用 Equatable 包,以便我们可以比较类的实例,而无需手动覆盖“==”和 hashCode。

      Equatable 类允许我们比较两个对象是否相等。

      这是一个平等的例子。假设我们有以下类:

      class Person {
        final String name;
      
        const Person(this.name);
      }
      

      我们可以像这样创建 Person 的实例:

      void main() {
        final Person bob = Person("Bob");
      }
      

      稍后,如果我们尝试在生产代码或测试中比较 Person 的两个实例,我们会遇到问题。

      print(bob == Person("Bob")); // false
      

      为了能够比较 Person 的两个实例,我们需要更改我们的类以覆盖 == 和 hashCode,如下所示:

      class Person {
        final String name;
      
        const Person(this.name);
      
        @override
        bool operator ==(Object other) =>
          identical(this, other) ||
          other is Person &&
          runtimeType == other.runtimeType &&
          name == other.name;
      
        @override
        int get hashCode => name.hashCode;
      }
      

      现在如果我们再次运行以下代码:

      print(bob == Person("Bob")); // true
      

      它将能够比较不同的 Person 实例。

      因此,当覆盖“==”和 hashCode 时,您不必浪费时间编写大量样板代码。

      使用 Equatable like

      class Person extends Equatable
      

      在整体情况下;如果您尝试使用具有可变状态的 bloc,您将面临没有 Equatable 的问题。它使资源不可变降低了性能。创建副本比更改属性更昂贵。

      如果您不清楚我试图解释的内容,阅读this 可能会对您有所帮助。

      【讨论】:

      • 但是为什么我们需要flutter_bloc呢?只是当我们需要说(状态是某种状态)作为我们集团的例子时?
      • 因为性能问题,我更新了答案。你能检查一下吗?
      • 谢谢,我应该在每个类中实现(props)并在里面添加我的状态,还是在性能方面不重要?
      • 是否有示例说明如何实现相同但使用equatable?并排查看两者会改善这个答案。
      • 我编辑了答案。如果答案对您来说还不够,您也可以进行编辑。
      【解决方案3】:

      Equatable 为您覆盖 == 和 hashCode,因此您不必浪费时间编写大量样板代码。

      还有其他包实际上会为您生成样板文件;但是,您仍然需要运行代码生成步骤,这并不理想。

      使用Equatable,无需生成代码,我们可以更多地专注于编写令人惊叹的应用程序,而不是繁琐的任务。 而propsequatablegetter,它采用我们想要的属性
      虽然它不需要关注它,但我只将属性放入 props getter 它不是那么重要,但我建议您在here 中阅读更多信息

      【讨论】:

      • 但是为什么我们需要flutter_bloc呢?只是当我们需要说(状态是某种状态)作为我们集团的例子时?
      • 正如我所说的那样,使用它必须浪费您的时间编写大量样板代码。就像我们为什么使用 http 进行 api 请求或文本样式如何工作一样,您可以找到答案但对您没有帮助
      • 不,兄弟,您的示例不正确,因为我需要知道我们为什么使用它,您说 ovveride == 和哈希码,但您仍然没有回答我的问题,因为我的问题是关于为什么我们在 bloc (flutter_bloc) 中需要它,那么为什么我们需要在 bloc 中覆盖 == 和 hashCode? :)
      猜你喜欢
      • 2021-12-14
      • 2020-10-21
      • 2020-01-28
      • 2020-11-18
      • 1970-01-01
      • 2020-09-10
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      相关资源
      最近更新 更多