0

我正在尝试学习颤振中的 bloc 模式并使用bloc框架创建一个示例应用程序。该应用程序是一个计数器,在计数器文本字段下方有两个按钮。在单击TrueFalse按钮时,当前 Ii 只是分别递增和递减计数器。

我注意到的是,如果我在实现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);
  }); 

与内部的 UI 绑定StatefulWidget

 BlocBuilder<CounterBloc, CounterState>(builder: (context, snapshot) {
       .....
                child: Text(
                  snapshot.counter.toString(),
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontSize: 25.0,
                    color: Colors.white,
                  ),
                ),

     .....
 });

现在,如果我使用intas 状态,那么它在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 的评论的帮助下解决了这个问题。现在我每次都在通过新的状态

4

1 回答 1

2

问题不在于它是否是一个类,而在于不变性。

使用bloc,您的状态必须是不可变的。您不应该修改以前的状态,而是创建一个新的修改状态。

于 2019-08-19T10:42:56.630 回答