flutter - 为什么我不能在 build() 中使用 context.read,但我可以使用 Provider.of with listen: false?
问题描述
文档中说这些是相同的,context.read
只是Provider.of<x>(context, listen: false)
. 如果我尝试context.read
在构建方法中使用,控制台中也会出现错误,但它没有解释原因。
我还发现了这个话题:Provider.of(context, listen: false) 是否等同于 context.read()? 但它没有回答“为什么”。
解决方案
context.read
不允许在里面build
使用,因为在那里使用非常危险,并且有更好的解决方案可用。Provider.of
允许build
向后兼容。
总体而言,其文档中解释了为什么context.read
不允许内部的原因:build
如果该值仅用于事件,则不要在 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<Counter>().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 不刷新的错误。
推荐阅读
- string - Teradata SQL - 行/记录之间的字符串相似性
- java - java 1.3 到 1.4 文本资源本地元素(资源包)
- jquery - 如何修复输出为 [object Object] 的嵌套 json 循环
- azure - Vnet 内的负载平衡 ACI
- vb.net - 如果显示消息,为什么从组合框的文本字段中清除文本?
- python - 如何确定 tkinter 中 ttk.Button 使用的字体?
- javascript - 正则表达式用双换行符分隔段落
- ios - 为什么该网站无法在 Swift URLSession 中转换为 UTF8?
- javascript - 用 js 和 php 改变 div 背景颜色
- arrays - Qsort c中的char数组