【问题标题】:Does state as class requires SatefulWidget?作为类的状态是否需要 SatefulWidget?
【发布时间】:2019-12-24 13:44:21
【问题描述】:

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

我注意到的是,如果我在实现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内的UI绑定

 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 的评论的帮助下解决了这个问题。现在我每次都在传递新状态

【问题讨论】:

    标签: android flutter bloc statefulwidget statelesswidget


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      • 2021-08-29
      • 2013-02-24
      • 1970-01-01
      相关资源
      最近更新 更多