在文档中有说明,它们是相同的,context.read只是Provider.of(context,listen:false)的快捷方式。如果我尝试在build方法中使用context.read,则控制台中也会出现错误,但是它没有解释原因。
我也找到了这个主题:Is Provider.of(context, listen: false) equivalent of context.read()?但是它没有回答“为什么”。
[context.read
不允许在build
中使用,因为在此使用非常危险,并且有更好的解决方案。
Provider.of
中允许build
。
总体上,context.read
中解释了为什么不允许在build
中使用its documentation的原因:
<< [DO N'T在构建内调用[read],如果该值仅用于事件:
Widget build(BuildContext context) { // counter is used only for the onPressed of RaisedButton final counter = context.read<Counter>(); return RaisedButton( onPressed: () => counter.increment(), ); }
虽然此代码本身没有错误,但这是一种反模式。 重构小部件后,将来很容易导致错误 将在事件处理程序中调用[read]:counter
用于其他用途,但忘记将[read]更改为[watch]。CONSIDER
Widget build(BuildContext context) { return RaisedButton( onPressed: () { // as performant as the previous previous solution, but resilient to refactoring context.read<Counter>().increment(), }, ); }
[与以前的反模式具有相同的效率,但没有 易碎的缺点。使用[read]创建值永远不变的小部件DO N'T
Widget build(BuildContext context) { // using read because we only use a value that never changes. final model = context.read<Model>(); return Text('${model.valueThatNeverChanges}'); }
而如果发生其他变化,则不重建窗口小部件的想法是 很好,这不应该用[read]完成。 依靠[read]进行优化非常脆弱且依赖 详细说明。使用[select]过滤不需要的重建CONSIDER
Widget build(BuildContext context) { // Using select to listen only to the value that used final valueThatNeverChanges = context.select((Model model) => model.valueThatNeverChanges); return Text('$valueThatNeverChanges'); }
虽然比[read]更详细,但使用[select]更安全。 它不依赖于Model
上的实现细节,它使得 无法出现无法刷新用户界面的错误。