【问题标题】:Flutter 2.0 Navigator w/ Provider Gives Null Value Errors when PoppingFlutter 2.0 Navigator w/Provider 在弹出时给出空值错误
【发布时间】:2021-10-01 23:13:09
【问题描述】:

我目前在使用 Flutter 2.0 Navigator API 时遇到了一些数据竞争错误。我的商店是用 MobX 实现的,并通过Provider 传递下来。之后,我在全局存储上拉一个Observer,然后每次我的全局存储更新时重新更新Navigator(用于路由)。但是,在我点击WinnerPage 的顶部后退箭头之前,一切正常。它在屏幕上显示以下错误,并在稍后立即闪回正常:

Unexpected null value.

The relevant error-causing widget was WinnerView

因此,为了尝试进一步调试,我了解到当按下返回按钮时,winner 的值瞬间为null(来自Navigator 中的onPopPage),这会弹出状态。有谁知道是否有解决此问题的方法?这是我所有的代码:

商店

class GlobalStore extends Store {
  @observable
  String? winner;

  @action
  void setWinner(String? newWinner) => winner = newWinner;
}

应用设置

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "MyApp",
      home: Provider<GlobalStore>(
        create: (_) => GlobalStore(),
        child: Observer(builder: (context) {
          final store = Provider.of<GlobalStore>(context);
          return Navigator(
            pages: [
              FooPage(),
              if (store.winner != null)
                WinnerPage()
            ],
            onPopPage: (route, result) {
              if (!route.didPop(result)) {
                return false;
              }

              store.setWinner(null);

              return true;
            }
          );
        }),
      )
    );
  }
}

Foo 页面(默认)

class FooPage extends Page {
  const FooPage() : super(key: const ValueKey('Foo Page'));

  Route createRoute(BuildContext context) {
    return MaterialPageRoute(
        settings: this, builder: (BuildContext context) => FooView());
  }
}

class FooView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final store = Provider.of<GlobalStore>(context);
    return Scaffold(
      body: TextButton(
        child: const Text('Hello, world!'),
        onPressed: () {
          store.setWinner("You!");
        }
      )
    );
  }
}

获奖者页面

class WinnerPage extends Page {
  const WinnerPage() : super(key: const ValueKey('Winner Page'));

  Route createRoute(BuildContext context) {
    return MaterialPageRoute(
        settings: this, builder: (BuildContext context) => WinnerView());
  }
}

class WinnerView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final store = Provider.of<GlobalStore>(context);
    final winner = store.winner!; // error here!
    return Scaffold(
        appBar: AppBar(),
        body: Column(children: [Text('${winner} is the winner!')]));
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    我实际上自己解决了这个问题,虽然我找不到问题发生原因的完整解释,所以如果其他人有更好的答案,请写出来。无论如何,由于某种原因,我扩展Page 的方式似乎无法正常工作。因此,我将每个Navigator.pages 更改为如下所示:

    [
      // note: I am using the stateless widget views not pages
      MaterialPage(child: const FooView(), key: const ValueKey("FooPage")),
      if (store.winner != null)
        MaterialPage(child: const WinnerView(), key: const ValueKey("WinnerPage"))
    ]
    

    我也有预感,问题在于我只是扩展了Page,而不是MaterialPage,这可能不会有相同的行为。但是,我仍然不知道为什么在大约 1 小时的搜索之后它没有以其他方式工作。

    【讨论】:

      猜你喜欢
      • 2021-10-11
      • 2020-12-11
      • 2019-05-09
      • 2022-01-19
      • 2021-03-16
      • 2022-08-23
      • 2020-10-06
      • 2020-02-24
      • 2021-04-05
      相关资源
      最近更新 更多