Государство как класс требует SatefulWidget?
Я пытаюсь изучить шаблон блока во флаттере и создаю одно приложение-образец, используя bloc
фреймворк. Приложение представляет собой счетчик и имеет две кнопки, расположенные в текстовом поле счетчика. После нажатия на True
а также False
кнопка в настоящее время я просто увеличиваю и уменьшаем счетчик соответственно.
Что я заметил, так это то, что если я использую класс как государство при реализации Bloc
шаблон, то я должен написать StatefulWidget
, И наоборот, если я использую int
только тогда даже используя StatelessWidget
работает отлично.
Таким образом, меня смущает реализация одного и того же примера: использование класса в качестве состояния и примитивного типа данных в качестве состояния.
Вот мой код CounterBloc
код с состоянием, определенным как класс CounterState
enum CounterEvent { Increment, Decrement }
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterState counterState = new CounterState(counter: 0);
@override
// TODO: implement initialState
CounterState get initialState => counterState;
@override
Stream<CounterState> mapEventToState(CounterEvent event) async* {
// TODO: implement mapEventToState
switch (event) {
case CounterEvent.Decrement:
counterState.decrementCounter();
yield counterState;
break;
case CounterEvent.Increment:
counterState.incrementCounter();
yield counterState;
break;
}
}
}
мой CounterState
определяется следующим образом
class CounterState {
int counter = 0;
CounterState({this.counter});
void incrementCounter() {
counter++;
}
void decrementCounter() {
counter--;
}
}
Вот как я отправляю событие по нажатию кнопки
onPressed: () {
setState(() {
counterBloc.dispatch(CounterEvent.Increment);
});
Связывание с пользовательским интерфейсом внутри StatefulWidget
BlocBuilder<CounterBloc, CounterState>(builder: (context, snapshot) {
.....
child: Text(
snapshot.counter.toString(),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25.0,
color: Colors.white,
),
),
.....
});
Теперь, если я использую int
как состояние, то он прекрасно работает в StatelessWidget
,
Здесь CounterBloc
с целым числом
enum CounterEvent { Increment, Decrement }
class CounterBloc extends Bloc<CounterEvent, int> {
@override
// TODO: implement initialState
int get initialState => 0;
@override
Stream<int> mapEventToState(CounterEvent event) async* {
// TODO: implement mapEventToState
switch (event) {
case CounterEvent.Decrement:
yield currentState -1;;
break;
case CounterEvent.Increment:
yield currentState +1;;
break;
}
}
}
Обновить
enum CounterEvent { Increment, Decrement }
class CounterBloc extends Bloc<CounterEvent, CounterState> {
@override
// TODO: implement initialState
CounterState get initialState => CounterState(counter: 0);
@override
Stream<CounterState> mapEventToState(CounterEvent event) async* {
// TODO: implement mapEventToState
switch (event) {
case CounterEvent.Decrement:
CounterState counterState = CounterState(counter: currentState.counter);
counterState.decrementCounter();
yield counterState;
break;
case CounterEvent.Increment:
CounterState counterState = CounterState(counter: currentState.counter);
counterState.incrementCounter();
yield counterState;
break;
}
}
}
решили проблему с помощью комментария @Rémi Rousselet. Теперь я прохожу новое состояние каждый раз
1 ответ
Вопрос не в том, класс это или нет, а в неизменяемости.
С помощью bloc
Ваше государство должно быть неизменным. Вы не должны изменять предыдущее состояние, а вместо этого создавать новое измененное состояние.