Reputation: 52
I give the values to the event individually, but the values of the other variables are reset in the event. I did the same for the state. I defined a state with two variables that I gave to those values by copyWith in different places But every time an ion is sent, the state values return to their original state. Are the states and event in the block reset in each change of its values ????
main
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:test1/bloc/datatest_bloc.dart';
import 'package:test1/bloc/datatest_state.dart';
import 'package:test1/bloc/datatest_event.dart';
import 'bloc/datatest_bloc.dart';
main() {
runApp(MaterialApp(
home: BlocProvider<Databloc>(
create: (context) => Databloc(),
child: Home(),
),
));
}
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocBuilder<Databloc, DatatestState>(
builder: (context, state) {
return Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {
BlocProvider.of<Databloc>(context)
.add(DataEvent_name().copyWith(name: 'mohammd'));
},
child: Text('btn'),
),
ElevatedButton(
onPressed: () {
BlocProvider.of<Databloc>(context)
.add(DataEvent_name().copyWith(pass: 'passsss'));
},
child: Text('pass'),
),
],
),
);
},
),
);
}
}
event-bloc
}
class DataEvent_name extends DatatestEvent {
final String name;
final String pass;
DataEvent_name({ this.name='', this.pass=''});
DataEvent_name copyWith({String? name, String? pass}) {
return DataEvent_name(name: name ?? this.name, pass: pass ?? this.pass);
}
}
class DataEvent_pass extends DatatestEvent {}
class DataEvent_print extends DatatestEvent {}
state-class
class DatatestState {
final String name;
final String pass;
DatatestState({
this.name ='',
this.pass='',
});
DatatestState copyWith({
String? name,
String? pass,
}) {
return DatatestState(
name: name ?? this.name,
pass: pass ?? this.pass,
);
}
}
bloc-class
class Databloc extends Bloc<DatatestEvent, DatatestState> {
Databloc() : super(DatatestState());
final servisApi = ServisApi();
@override
Stream<DatatestState> mapEventToState(DatatestEvent event) async* {
if (event is DataEvent_name) {
yield DatatestState(name: event.name, pass: event.pass);
servisApi.PrintState(a: state.name, b: state.pass);
}
}
}
outpout
flutter: a:mohammd b:
flutter: a: b:passsss
flutter: a:mohammd b:
flutter: a: b:passsss
flutter: a:mohammd b:
flutter: a: b:passsss
Upvotes: 1
Views: 4081
Reputation: 26
BLoC
design pattern helps separate the presentation layer from the business logic.
Events
are the input to a Bloc. They are commonly UI events such as button presses. Events are dispatched and then converted to States.
States
are the output of a Bloc. Presentation components can listen to the stream of states and redraw portions of themselves based on the given state.
Transitions
occur when an Event is dispatched after mapEventToState
has been called but before the Bloc's state has been updated. A Transition consists of the currentState, the event which was dispatched, and the nextState.
Coming to the example you shown, you have having 2 button in UI:
btn : You are triggering an event DataEvent_name by passing only Name argument as "mohammd". Hence, a final state is having a value as name:'mohammd' and pass:''.
Since you are printing the current state value, hence the output is :
a:mohammd b:
pass: You are triggering an event DataEvent_name by passing only pass argument as "passsss". Hence, a final state is having a value as name: '' and pass:'passsss'. Since you are printing the current state value, hence the output is :
a: b:passsss
Are the states and event in the block reset in each change of its values
Event are just the input. It is a carrier of data from UI so that required data is available while doing a business logic. As state are the output of an event, in the entire BLoC it can have only one state at a time. Hence, yes it will update the earlier state. It depends on the use case if we want to reset entirely or update certain values in the existing state.
How to update existing state
In mapEventToState
, we are having access to the current state using state
variable. So while yielding a new state, we can pass the data from current state as well based on the required use case.
In your example: If you want to maintain the old value of name & pass if its blank:
yield DatatestState(
name: event.name == '' ? state.name : event.name,
pass: event.pass == '' ? state.pass : event.pass);
It will return the below output:
a:mohammd b:
a:mohammd b:passsss
Upvotes: 1