gpt4 book ai didi

flutter - 为什么我不能在 build() 中使用 context.read,但我可以使用 Provider.of 和 listen : false?

转载 作者:行者123 更新时间:2023-12-03 02:38:52 24 4
gpt4 key购买 nike

文档中声明这些是相同的,并且 context.read只是 Provider.of<x>(context, listen: false) 的快捷方式.
如果我尝试使用 context.read,控制台中也会出现错误在构建方法中,但它没有解释原因。
我也发现了这个话题:Is Provider.of(context, listen: false) equivalent to context.read()?
但它没有回答“为什么”。

最佳答案

  • context.read不允许进入 build因为在那里使用非常危险,并且有更好的解决方案。
  • Provider.of允许在 build为了向后兼容。

  • 总的来说,背后的原因 context.read不允许进入 build解释在 its documentation :

    DON'T call [read] inside build if the value is used only for events:

    Widget build(BuildContext context) {
    // counter is used only for the onPressed of RaisedButton
    final counter = context.read<Counter>();

    return RaisedButton(
    onPressed: () => counter.increment(),
    );
    }

    While this code is not bugged in itself, this is an anti-pattern. It could easily lead to bugs in the future after refactoring the widget to use counter for other things, but forget to change [read] into [watch].

    CONSIDER calling [read] inside event handlers:

    Widget build(BuildContext context) {
    return RaisedButton(
    onPressed: () {
    // as performant as the previous previous solution, but resilient to refactoring
    context.read<Counter>().increment(),
    },
    );
    }

    This has the same efficiency as the previous anti-pattern, but does not suffer from the drawback of being brittle.

    DON'T use [read] for creating widgets with a value that never changes

    Widget build(BuildContext context) {
    // using read because we only use a value that never changes.
    final model = context.read<Model>();

    return Text('${model.valueThatNeverChanges}');
    }

    While the idea of not rebuilding the widget if something else changes is good, this should not be done with [read]. Relying on [read] for optimisations is very brittle and dependent on an implementation detail.

    CONSIDER using [select] for filtering unwanted rebuilds

    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');
    }

    While more verbose than [read], using [select] is a lot safer. It does not rely on implementation details on Model, and it makes impossible to have a bug where our UI does not refresh.

    关于flutter - 为什么我不能在 build() 中使用 context.read,但我可以使用 Provider.of 和 listen : false?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62432759/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com