Государство как класс требует 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Ваше государство должно быть неизменным. Вы не должны изменять предыдущее состояние, а вместо этого создавать новое измененное состояние.

Другие вопросы по тегам