【问题标题】:Problem in using Provider in flutter when listen:true听时在颤动中使用 Provider 的问题:true
【发布时间】:2020-06-19 21:30:42
【问题描述】:

我正在使用 Flutter 开发一个应用程序。我尝试在应用程序中使用 Provider,但遇到了这个错误:

Tried to listen to a value exposed with provider, from outside of the widget tree.
E/flutter ( 2850): 
E/flutter ( 2850): This is likely caused by an event handler (like a button's onPressed) that called
E/flutter ( 2850): Provider.of without passing `listen: false`.
E/flutter ( 2850): 
E/flutter ( 2850): To fix, write:
E/flutter ( 2850): Provider.of<Complexes>(context, listen: false);
E/flutter ( 2850): 
E/flutter ( 2850): It is unsupported because may pointlessly rebuild the widget associated to the
E/flutter ( 2850): event handler, when the widget tree doesn't care about the value.

我的代码是:

loadedComplexes = Provider.of<Complexes>(context, listen: true).favoriteItems;

设置为listen:false时,问题解决。但我认为这不是解决这个问题的好方法。另外,我需要提供者来听。我已经搜索了互联网,但找不到任何合适的解决方案。

这是我的 Flutter 医生:

[√] Flutter (Channel stable, v1.12.13+hotfix.7, on Microsoft Windows [Version 10.0.18363.657],    locale en-US)
   • Flutter version 1.12.13+hotfix.7 at C:\android\flutter
   • Framework revision 9f5ff2306b (6 weeks ago), 2020-01-26 22:38:26 -0800
   • Engine revision a67792536c
   • Dart version 2.7.0

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at C:/android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 28.0.3
    • ANDROID_HOME = C:/android/sdk
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)
    • All Android licenses accepted.

[√] Android Studio (version 3.6)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin version 43.0.2
    • Dart plugin version 192.7761
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

[√] IntelliJ IDEA Ultimate Edition (version 2019.3)
    • IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.4
    • Flutter plugin version 42.1.4
    • Dart plugin version 193.5731

[!] VS Code (version 1.41.1)
    • VS Code at C:\Users\Altay\AppData\Local\Programs\Microsoft VS Code
    X Flutter extension not installed; install from
      https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[√] Connected device (1 available)
    • Android SDK built for x86 • emulator-5554 • android-x86 • Android 5.0.2 (API 21) (emulator)

! Doctor found issues in 1 category.
Process finished with exit code 0

我的提供商块:

return MultiProvider(
  providers: [
    ChangeNotifierProvider(
      create: (ctx) => Salons(),
    ),
    ChangeNotifierProvider(
      create: (ctx) => Cities(),
    ),
    ChangeNotifierProvider(
      create: (ctx) => Auth(),
    ),
    ChangeNotifierProvider(
      create: (ctx) => Complexes(),
    ),
    ChangeNotifierProvider(
      create: (ctx) => UserInfo(),
    ),
    ChangeNotifierProvider(
      create: (ctx) => User(),
    ),
  ],
  child: MaterialApp(........

调用提供者的方法:

Future<void> _submit() async {
    loadedComplexes.clear();
    loadedComplexes =
        Provider.of<Complexes>(context, listen: true).favoriteItems;
    loadedComplexestolist.addAll(loadedComplexes);
}

如有必要,我可以提供更多信息。这个问题有解决办法吗?

提前致谢。

【问题讨论】:

  • 您能否分享一下您定义 BlocProvider 的确切位置以及调用 BlocProvider.of(context) 的确切时间,以便我们轻松为您提供帮助。另请查看 Provider 包中的示例应用程序以获取详细参考。
  • @Darish 我更新了问题并添加了提供程序块

标签: android ios android-studio flutter provider


【解决方案1】:

错误清楚地表明您在Widget 树之外声明它。 如果要将 listen 设置为 true,则必须在 Widget 树中声明它,以便提供者知道发生更改时必须重建哪个 Widget 树。

示例

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
 loadedComplexes = Provider.of<Complexes>(context, listen: true).favoriteItems;//You must declare here if listen to true
  return Scaffold(
    body: Center(
      child: MyWidget(),
    ),
 );

} }

listen 设置为true 使整个小部件成为侦听器并导致重建整个小部件树。但是设置听 false 将帮助您重建您声明为 Consumer 的特定小部件(消费者是监听更改的小部件)。

check this video mate. He uses the same approach as you did

【讨论】:

  • 即使听错了消费者重建?消费者比供应商贵吗?请解释 。谢谢
【解决方案2】:

如果listen 应该是true,则提供者不会有这个标志。

您所处的情况需要listen:false 是有原因的。这是正确的解决方案。

【讨论】:

  • 嗨 Rémi Rousselet,是否可以在消费者内部添加事件处理程序,它将与构建方法分开。比如处理完毕不想再打开另一个画面,怎么处理?
【解决方案3】:

我刚刚改了

Provider.of(context);

context.watch();

注意:Provider 只能监听 build() 和 didChangeDependencies() 方法。 initState() 方法不起作用。

【讨论】:

    【解决方案4】:

    设置为 false 是不错的做法。它在访问提供者值一次或调用提供者方法时使用。

    如果您想收听更新,您可以选择a number of different providers

    【讨论】:

      【解决方案5】:

      替换你的代码的这个 sn-p

      create: (ctx) =>
      

      何去何从

      create: (ctx, listen: false) => 
      

      【讨论】:

        猜你喜欢
        • 2019-03-16
        • 1970-01-01
        • 1970-01-01
        • 2021-05-16
        • 2013-05-17
        • 2022-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多