我很多方法都是build外部调用Provider方法,即使是渲染完成之后,调用也会报错
Error: Could not find the correct Provider<SearchHistoryProvider> above this SearchPage Widget
I/flutter (22348):
I/flutter (22348): This happens because you used a `BuildContext` that does not include the provider
I/flutter (22348): of your choice. There are a few common scenarios:
看下我的代码结构
class SearchPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// ❌ 这样写 Provider 的作用域只在 SearchPage 这个 build 方法中,
return ChangeNotifierProvider(
create: (_) => SearchHistoryProvider(),
child: Scaffold(
// 这里读取会出错
body: Consumer<SearchHistoryProvider>(
builder: (context, provider, _) => ...
),
),
);
}
}
问题就在于ChangeNotifierProvider的子元素不能不是一个部件(比如Scaffold),必须是一个类,
原因就是Scaffold直接访问的context,是 SearchPage 的 context,而不是 Provider 插入后新的 context
class SearchPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => SearchHistoryProvider(),
child: Scaffold(
// 这里的 context 是 SearchPage 的 context,
// 而不是 Provider 插入后新的 context。
),
);
}
}
所以,正解就是
// 包裹 Provider 的外部页面
class SearchWrapperPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => SearchHistoryProvider(),
child: SearchPage(), // SearchPage 是 Provider 的 child,可以正常读取 Provider
);
}
}
// 真正使用 Provider 的页面,这样即使方法在build外部,也能正常调用Provider实例
class SearchPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final provider = context.watch<SearchHistoryProvider>(); // ✅ 这里就没问题了
return Scaffold(
appBar: AppBar(title: Text('Search')),
body: Text()
);
}
}