Flutter bloc 未在 7.2.0 版本中使用 Equatable 进行重建

Dmy*_*ian 5 state-management dart flutter bloc

我创建了简单的应用程序来测试 bloc 7.2.0,并发现 BlocBuilder 在第一次成功重建后不会重建。在每个其他触发器上,bloc 都会发出新状态,但 BlocBuilder 会忽略它。

请注意,如果我 extends Equatable从状态和事件中删除及其覆盖,则每次按下按钮时 BlocBuilder 都会重建 UI。颤振版本2.5.1

如果 Equatable 是必要的,为什么它不能使用它呢?如果 Equatable 不是必需的,为什么在通过 VSCode 扩展进行初始创建时使用它。

我的代码:

块部分

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';

//bloc
class MainBloc extends Bloc<MainEvent, MainState> {
  MainBloc() : super(MainInitial()) {
    on<MainButtonPressedEvent>(_onMainButtonPressedEvent);
  }

  void _onMainButtonPressedEvent(
      MainButtonPressedEvent event, Emitter<MainState> emit) {
    emit(MainCalculatedState(event.inputText));
  }
}

//states
abstract class MainState extends Equatable {
  const MainState();

  @override
  List<Object> get props => [];
}

class MainInitial extends MainState {}

class MainCalculatedState extends MainState {
  final String exportText;
  const MainCalculatedState(this.exportText);
}

//events
abstract class MainEvent extends Equatable {
  const MainEvent();

  @override
  List<Object> get props => [];
}

class MainButtonPressedEvent extends MainEvent {
  final String inputText;
  const MainButtonPressedEvent(this.inputText);
}
Run Code Online (Sandbox Code Playgroud)

用户界面部分

import 'package:bloc_test/bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: BlocProvider(
          create: (context) => MainBloc(),
          child: SubWidget(),
        ),
      ),
    );
  }
}

class SubWidget extends StatelessWidget {
  TextEditingController inputText = TextEditingController();
  String? exportText;

  @override
  Widget build(BuildContext context) {
    MainBloc mainBloc = BlocProvider.of<MainBloc>(context);

    return BlocBuilder<MainBloc, MainState>(
      builder: (context, state) {
        if (state is MainCalculatedState) {
          exportText = state.exportText;
        }
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('${exportText ?? ''} data'),
              SizedBox(
                width: 200,
                child: TextField(
                  controller: inputText,
                ),
              ),
              ElevatedButton(
                  onPressed: () =>
                      mainBloc.add(MainButtonPressedEvent(inputText.text)),
                  child: const Text('Button')),
            ],
          ),
        );
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

nvo*_*igt 12

Equatable 用于让您轻松编程,了解状态如何以及何时相同(不更新)以及何时不同(更新)。

您的更新不起作用,因为您重复发送相同的状态,但您没有告诉 Equatable 扩展如何找出它们是否不同。所以它们都是一样的。

因此,为了确保您的程序了解同类的某些状态确实不同并且应该导致更新,您需要确保提及使它们不同的原因:

class MainCalculatedState extends MainState {
  final String exportText;
  const MainCalculatedState(this.exportText);

  // this tells the Equatable base class to consider your text property
  // when trying to figure out if two states are different.
  // If the text is the same, the states are the same, so no update
  // If the text is different, the states are different, so it will update 
  @override
  List<Object> get props => [this.exportText];
}
Run Code Online (Sandbox Code Playgroud)

如果你完全删除 Equatable ,两个新实例化的状态永远不会相等,所以这也可以解决你的问题......除了在某些时候你会希望它们相等,然后你需要将其添加回来。