使用带有flutter_bloc的Equatable类

Posted

技术标签:

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

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

abstract class LoginStates extends Equatable

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


【问题讨论】:

【参考方案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? :)

以上是关于使用带有flutter_bloc的Equatable类的主要内容,如果未能解决你的问题,请参考以下文章

使用 flutter_bloc 库有啥缺点

由于某种原因不能使用flutter_bloc

使用flutter_bloc提交时如何验证表单?

将flutter_bloc与tabview一起使用

flutter_bloc :使 initialState 方法异步

Flutter_bloc 从没有 UI 事件的 firestore 获取更新的数据