关于 flutter 的 provider 中发生的错误 [英] About errors that occur in flutter's provider

查看:587
本文介绍了关于 flutter 的 provider 中发生的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在了解 Flutter 的提供者,但我遇到了一个错误.

I'm learning about flutter's provider and I'm suffering from one error.

以下代码有效.

[code1]
class Model extends ChangeNotifier {
  void save() {
    print('save');
  }
}
class Main extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Model(),
      child: Scaffold(
        appBar: AppBar(
          title: Text('test'),
        ),
        body: NewWidget(),
      ),
    );
  }
}

class NewWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: Text(
        "test",
      ),
      onPressed: () {
        context.read<Model>().save();
      },
    );
  }
}

但是下面的代码不起作用.

But the code below does not work.

[code2]
class Model extends ChangeNotifier {
  void save() {
    print('save');
  }
}

class Main extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Model(),
      child: Scaffold(
        appBar: AppBar(
          title: Text('test'),
        ),
        body: RaisedButton(
          child: Text(
            "test",
          ),
          onPressed: () {
            context.read<Model>().save();
          },
        ),
      ),
    );
  }
}

使用此代码,按下按钮时会输出以下错误.

With this code, the following error is output when the button is pressed.

Error: Could not find the correct Provider<Model> above this Main Widget

This likely happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:

- The provider you are trying to read is in a different route.

  Providers are "scoped". So if you insert of provider inside a route, then
  other routes will not be able to access that provider.

- You used a `BuildContext` that is an ancestor of the provider you are trying to read.

  Make sure that Main is under your MultiProvider/Provider<Model>.
  This usually happen when you are creating a provider and trying to read it immediatly.

  For example, instead of:

我不分离小部件,我想写一个像 code2 这样的小部件.
有什么好的方法请告诉我.

I don't separate widgets, I want to write one widget like code2.
Please let me know if there is any good way.

谢谢!

推荐答案

在您的第一个示例中,NewWidget 是使用新的 BuildContext 构建的,该BuildContext 已经可以访问它的祖先,所以这个小部件可以看到你在那里创建的提供者:context.read().

In your first example, NewWidget is build with a new BuildContext, that already have access to it's ancestor, so this Widget can see the provider that you have created there with: context.read<Model>().

但是,在你的第二个例子中,你在同一个小部件 Main 中创建和使用你的提供者,所以所有的东西都在同一个 BuildContext 上,当你运行 context.read() flutter 将尝试在您的 Widget 树中查找 Model,但它找不到它,因为您刚刚创建了它.在这种情况下,您可以使用 Builder 小工具:

But, on your second example, you are creating and using your provider all in the same Widget Main so everything on the same BuildContext, and when you run context.read<Model>() flutter will try to look up in your Widget tree to find the Model, but it won't find it because you have just created it. That's a scenario where you could make use, of the Builder Widget:

class Main extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Model(),
      child: Scaffold(
        appBar: AppBar(
          title: Text('test'),
        ),
        body: Builder(
          // Here the magic happens
          // this builder function will generate a new BuilContext for you
          builder: (BuildContext newContext){
            return RaisedButton(
              child: Text(
                "test",
              ),
              onPressed: () {
                 newContext.read<Model>().save();
              },
            );
          }
        ),
      ),
    );
  }
}

通过使用 Builder 小部件,您可以创建一个新的 BuildContext 可用于检索有关您刚刚创建的提供程序的信息,这是因为您的Builder 小部件,是在您的 ChangeNotifierProvider 之后构建的,它是它的子代,因此它可以轻松地在其父代上查找和找到此信息.

By using the Builder Widget, you have the ability to create a new BuildContext the can be used to retrieve information about the provider you have just created, that's because your Builder widget, is build after your ChangeNotifierProvider, and it is a child of it, so it can easily look up and find this information on it's parent.

还要注意错误告诉您的内容,flutter 编译器在处理此类问题时非常聪明:

Also pay attention on what errors tell you, flutter compiler is really smart with that kind of issues:

确保 Main 在您的 MultiProvider/Provider 下.这通常发生在您创建提供程序并尝试读取它时立即.

Make sure that Main is under your MultiProvider/Provider. This usually happen when you are creating a provider and trying to read it immediatly.

这些行告诉你我之前解释过的内容.

These lines tell you exactly what I explained before.

这篇关于关于 flutter 的 provider 中发生的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆