Ser*_*sky 28 provider dart flutter
文档中指出这些是相同的,context.read只是Provider.of<x>(context, listen: false). 如果我尝试context.read在构建方法中使用,控制台中也会出现错误,但它没有解释原因。
我还发现了这个话题:Is Provider.of(context, listen: false) 等价于 context.read()? 但它没有回答“为什么”。
Rém*_*let 35
context.read不允许进入,build因为在那里使用非常危险,并且有更好的解决方案。
Provider.of允许build向后兼容。
总的来说,其文档中解释了为什么context.read不允许进入的原因:build
如果该值仅用于事件,请不要在 build 内部调用 [read]:
Run Code Online (Sandbox Code Playgroud)Widget build(BuildContext context) { // counter is used only for the onPressed of RaisedButton final counter = context.read<Counter>(); return RaisedButton( onPressed: () => counter.increment(), ); }虽然这段代码本身并没有被窃听,但这是一种反模式。将widget重构
counter为其他东西后很容易导致日后的bug ,但是忘记把[read]改成[watch]。考虑在事件处理程序中调用 [read]:
Run Code Online (Sandbox Code Playgroud)Widget build(BuildContext context) { return RaisedButton( onPressed: () { // as performant as the previous previous solution, but resilient to refactoring context.read<Counter>().increment(), }, ); }这与之前的反模式具有相同的效率,但没有脆弱的缺点。
不要使用 [read] 来创建一个值永远不会改变的小部件
Run Code Online (Sandbox Code Playgroud)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] 过滤不需要的重建
Run Code Online (Sandbox Code Playgroud)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 不刷新的错误。
小智 5
问题是您尝试在小部件完成构建之前调用上下文,以在小部件完成构建后运行代码,将代码提供给后帧回调函数。
例如:
WidgetsBinding.instance.addPostFrameCallback((_) {
// your code in here
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9926 次 |
| 最近记录: |