首页 > 解决方案 > Flutter w/ MobX:发生异常时,Snackbar 不会出现

问题描述

我尝试使用 http 包从 Internet 获取 API,并且我正在使用 MobX 进行状态管理。我遇到的问题是,当从 Internet 获取数据时发生异常时,尽管控制台中没有打印未处理的异常错误,但小吃栏不会弹出显示错误消息。这是与问题相关的代码。

主页

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  QuestionStore _store;
  List<ReactionDisposer> _reactionDisposer;
  GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _store ??= Provider.of<QuestionStore>(context);
    _reactionDisposer ??= <ReactionDisposer>[
      reaction(
        // Checking the error message, if error message is not null
        // show snackbar showing the error message
        //TODO: Fix snackbar won't show up
        (_) => _store.errorMessage,
        (String message) {
          _scaffoldKey.currentState.showSnackBar(
            SnackBar(
              content: Text(message),
            ),
          );
        },
      )
    ];
  }

  @override
  void dispose() {
    _reactionDisposer.forEach((reaction) => reaction());
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    ScreenConfig().init(context);

    return Scaffold(
      body: Observer(
        builder: (_) {
          switch (_store.state) {
            case StoreState.loading:
              return Center(child: CircularProgressIndicator());

            case StoreState.initial:
              return UserInput();

            case StoreState.loaded:
              return CustomScrollView(
                slivers: [
                  CustomSliverAppBar(question: _store.questionsData),
                  CustomSliverList(question: _store.questionsData),
                ],
              );

              break;
          }

          return Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

状态管理

part 'question_store.g.dart';

class QuestionStore = _QuestionStore with _$QuestionStore;

enum StoreState {initial, loading, loaded}

abstract class _QuestionStore with Store {
  final QuestionsService questionsService = QuestionsService();

  @observable
  ObservableFuture<CoreData> questionFuture;

  @observable
  CoreData questionsData;

  @observable
  String errorMessage;

  @computed
  StoreState get state {
    if (questionFuture == null ||
        questionFuture.status == FutureStatus.rejected) {
      return StoreState.initial;
    }
    return questionFuture.status == FutureStatus.pending
        ? StoreState.loading
        : StoreState.loaded;
  }
  @action
  Future fetchQuestionData(String value) async{
    try{
      errorMessage = null;
      questionFuture = ObservableFuture(
        questionsService.fetchQuestion(value).then((value) => value));
      questionsData = await questionFuture;
    // If there is an error, give errorMessage a String value
    // of the error
    } on HttpException {
      errorMessage = "Error 404: Data Not Found";
    } on SocketException{
      errorMessage = "Internet Not Found";
    } on FormatException {
      errorMessage = "Not valid url";
    }
  }
}

解析JSON文件的文件

class QuestionsService {
  Future<CoreData> fetchQuestion(String url) async {
    final response = await http.get(url);
    ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity());
    if (response.statusCode == 200) {
      var jsonResponse = convert.jsonDecode(response.body);
      CoreData parsedQuestions = CoreData.fromJson(jsonResponse);

      return parsedQuestions;

    } else if (connectivityResult == ConnectivityResult.none) {
      throw SocketException("Internet connection not found");

    } else if (response.statusCode == 404) {
      throw HttpException("Error 404");
      
    } else {
      throw FormatException();
    }
  }
}

标签: flutterdart

解决方案


我设法解决了这个问题。问题不在 MobX 文件或用于解析 JSON 数据的文件中。它在主页文件中。我忘记在脚手架小部件中添加密钥

return Scaffold(
  key: _scaffoldKey // Add the key
  body: //...

现在,如果出现错误,应该会出现小吃吧。


推荐阅读