【问题标题】:Flutter Riverpod StateNotifier load data on page buildFlutter Riverpod StateNotifier 在页面构建时加载数据
【发布时间】:2021-03-26 02:16:12
【问题描述】:

我正在开发一个新的应用程序并使用状态通知器测试 Riverpod,并且有一个关于在构建页面时可以在哪里加载初始数据的问题。

我有以下状态类:

abstract class SalesOrderListState extends Equatable {
  const SalesOrderListState();

  @override
  List<Object> get props => [];
}

class SalesOrderListInitial extends SalesOrderListState {}

class SalesOrderListLoading extends SalesOrderListState {}

class SalesOrderListSuccess extends SalesOrderListState {
  final List<SalesOrderListItem> salesOrderListItems;

  SalesOrderListSuccess({
    @required this.salesOrderListItems,
  });

  @override
  List<Object> get props => [salesOrderListItems];
}

class SalesOrderListError extends SalesOrderListState {
  final String error;

  const SalesOrderListError({@required this.error});

  @override
  List<Object> get props => [error];
}

还有这个 state_notifier 类:

final salesOrderListStateNotifierProvider =
    StateNotifierProvider<SalesOrderListStateNotifier>(
        (ref) => SalesOrderListStateNotifier(ref.read));

class SalesOrderListStateNotifier extends StateNotifier<SalesOrderListState> {
  final Reader read;

  SalesOrderListStateNotifier(this.read) : super(SalesOrderListInitial());

  Future<void> getSalesOrders() async {
    final SalesOrderListUseCase _salesOrderListUseCase =
        read(salesOrderListUseCaseProvider);

    state = SalesOrderListLoading();
    final result = await _salesOrderListUseCase.getSalesOrders();
    result.fold(
      (failure) =>
          state = SalesOrderListError(error: mapFailureToMessage(failure)),
      (salesOrderListItems) async {
          state = SalesOrderListSuccess(salesOrderListItems: salesOrderListItems);
      },
    );
  }
}

现在我的 widged 类(页面)像这样使用状态通知器:

 ...

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(),
      ),
      body: Consumer(
        builder: (context, watch, child) {
          final state = watch(salesOrderListStateNotifier.state);
          switch (state.runtimeType) {
            case SalesOrderListSuccess:
              final _salesOrders = (state as SalesOrderListSuccess).salesOrderListItems;
              ...
                 print sales orders
              ...
              );
              break;
            case SalesOrderListError:
              return MessageDisplayWidget(
                message: (state as SalesOrderListError).error,
              );
              break;
            default:
              return LoadingWidget();
          }
        },
      ),
    );
  }

但在页面加载之前,我必须调用

context
.read(salesOrderListStateNotifierProvider)
.getSalesOrders()

最好的方法是什么?

我已经尝试过使用 statefull 小部件并像这样覆盖 initstate

void initState() {
    super.initState();
    Future.delayed(Duration.zero).then(
      (_) => context
          .read(salesOrderListStateNotifierProvider)
          .getSalesOrders(),
    );
    // WidgetsBinding.instance.addPostFrameCallback(
    //   (_) => context
    //       .read(salesOrderListStateNotifierProvider)
    //       .getSalesOrders(),
    // );
  }

这可行,但我不确定这是否是最好的方法。

我有很多页面必须在绘制数据之前加载数据,我不确定将所有这些页面转换为有状态的小部件以覆盖 initstate 是否是最佳解决方案。

【问题讨论】:

    标签: flutter flutter-state riverpod


    【解决方案1】:

    github上@iamarnas给了我解决方法,在statenotifier构造函数里面调用fetch方法

    class UserNotifier extends StateNotifier<User>{
      UserNotifier() : super(User()){
        fetchData(); // It's same as initState();
      } 
    }
    

    【讨论】:

    • 嗨,Alex,我有同样的问题,想知道解决方案。在您的情况下,您是否像这样在构造函数中调用该方法: SalesOrderListStateNotifier(this.read) : super(SalesOrderListInitial() { getSalesOrder() });谢谢
    • 是的,我只是在构造函数里面调用方法
    【解决方案2】:

    我在 init 上调用 api 时遇到了同样的问题。在 initState 中使用 WidgetBinding 会解决这个问题。

    WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
     context.read(salesOrderListStateNotifierProvider).getSalesOrders()
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-01
      • 2021-04-04
      • 2021-03-17
      • 2021-04-21
      • 1970-01-01
      • 1970-01-01
      • 2021-08-11
      • 1970-01-01
      相关资源
      最近更新 更多