context.read
禁止在内部使用,build
因为在该处使用非常危险,并且有许多更好的解决方案。Provider.of
允许build
向后兼容。
总体而言,其文档中解释了为什么
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 resilientto 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不会刷新的错误。



