关于 flutter 的 provider 中发生的错误 [英] About errors that occur in flutter's 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屋!