在文档中指出它们是相同的,context.read只是的快捷方式Provider.of<x>(context, listen: false)。如果我尝试context.read在build方法中使用,控制台中也会出现错误,但这并不能解释原因。
context.read
Provider.of<x>(context, listen: false)
我也发现了这个主题:Provider.of(context,listen:false)是否等同于context.read()? 但是它没有回答“为什么”。
context.read禁止在内部使用,build因为在该处使用非常危险,并且有许多更好的解决方案。
build
Provider.of允许build向后兼容。
Provider.of
总体而言,其文档中解释了为什么context.read不允许在内部build进行解释的原因:
*如果该值仅用于事件,则 *不要 在内部调用[read]: Widget build(BuildContext context) { // counter is used only for the onPressed of RaisedButton final counter = context.read<Counter>(); return RaisedButton( onPressed: () => counter.increment(), ); } 尽管此代码本身并未出错,但这是一种反模式。重构小部件以counter用于其他用途后,将来很容易导致错误,但忘记将[read]更改为[watch]。 考虑 在事件处理程序中调用[read]: Widget build(BuildContext context) { return RaisedButton( onPressed: () { // as performant as the previous previous solution, but resilient to refactoring context.read().increment(), }, ); } 这具有与先前的反模式相同的效率,但是没有易碎的缺点。 不要 使用[read]创建值永远不变的小部件 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]过滤不必要的重建 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,并且不可能出现UI不会刷新的错误。
*如果该值仅用于事件,则 *不要 在内部调用[read]:
Widget build(BuildContext context) { // counter is used only for the onPressed of RaisedButton final counter = context.read<Counter>(); return RaisedButton( onPressed: () => counter.increment(), ); }
尽管此代码本身并未出错,但这是一种反模式。重构小部件以counter用于其他用途后,将来很容易导致错误,但忘记将[read]更改为[watch]。
counter
考虑 在事件处理程序中调用[read]:
Widget build(BuildContext context) { return RaisedButton( onPressed: () { // as performant as the previous previous solution, but resilient
to refactoring context.read().increment(), }, ); }
这具有与先前的反模式相同的效率,但是没有易碎的缺点。
不要 使用[read]创建值永远不变的小部件
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]过滤不必要的重建
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,并且不可能出现UI不会刷新的错误。
Model