Flutter bloc 未在 7.2.0 版本中使用 Equatable 进行重建
Flutter bloc is not rebuilding in 7.2.0 version with Equatable
我创建了简单的应用程序来测试 bloc 7.2.0,并遇到了 BlocBuilder 在第一次成功重建后不重建的问题。在每个其他触发器上,bloc 都会发出新状态,但 BlocBuilder 会忽略它。
请注意,如果我从状态和事件中删除 extends Equatable
及其覆盖,则每次按下 Button 时 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);
}
UI部分
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')),
],
),
);
},
);
}
}
您的 MainCalculatedState
需要覆盖 Equatable
中的 props
getter 和 return 应该用于评估平等的所有属性的列表。在您的情况下,它应该 return [exportText]
。
示例:
class MainCalculatedState extends MainState {
final String exportText;
const MainCalculatedState(this.exportText);
@override
List<Object> get props => [exportText];
}
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];
}
如果你完全删除 Equatable,两个新实例化的状态 永远不会 相等,所以这也可以解决你的问题......除了在某些时候你会希望它们是,然后你需要把它加回去。
我创建了简单的应用程序来测试 bloc 7.2.0,并遇到了 BlocBuilder 在第一次成功重建后不重建的问题。在每个其他触发器上,bloc 都会发出新状态,但 BlocBuilder 会忽略它。
请注意,如果我从状态和事件中删除 extends Equatable
及其覆盖,则每次按下 Button 时 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);
}
UI部分
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')),
],
),
);
},
);
}
}
您的 MainCalculatedState
需要覆盖 Equatable
中的 props
getter 和 return 应该用于评估平等的所有属性的列表。在您的情况下,它应该 return [exportText]
。
示例:
class MainCalculatedState extends MainState {
final String exportText;
const MainCalculatedState(this.exportText);
@override
List<Object> get props => [exportText];
}
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];
}
如果你完全删除 Equatable,两个新实例化的状态 永远不会 相等,所以这也可以解决你的问题......除了在某些时候你会希望它们是,然后你需要把它加回去。