从 Provider 迁移到 Riverpod 时出错:“ChangeNotifierProvider”不是函数

问题描述 投票:0回答:2

我正在将我的 Flutter 应用程序从使用 Provider 包迁移到 Riverpod 进行状态管理。但是,我遇到了一个障碍,并显示以下错误消息:

“ChangeNotifierProvider”不是一个函数。尝试将名称更正为 匹配现有函数,或定义名为的方法或函数 'ChangeNotifierProvider'

在我的主应用程序文件中尝试将

Provider
替换为 Riverpod 等效项后,在编译期间出现此错误。

我的目标是利用 Riverpod 的增强功能和可扩展性。我对使用它的

ChangeNotifierProvider
来管理应用程序状态特别感兴趣。

我尝试过的:

  • 查看 Riverpod 文档以获取迁移提示。
  • 搜索了类似的错误消息,但没有找到解决我从 Provider 到 Riverpod 的特定转换的问题。

代码示例:

void main() async {
  await Hive.initFlutter();
  await Hive.openBox("Habit_Database");

  runApp(MultiProvider(providers: [
    ChangeNotifierProvider(
      create: (context) => UserProvider(),
    ),
  ], child: const MyApp()));
}

问题:如何正确地将

ChangeNotifierProvider
从Provider迁移到Riverpod,解决上述错误?任何具体示例或文档参考将不胜感激。

提前感谢您的帮助!

flutter dart provider riverpod state-management
2个回答
3
投票

我现在正在为客户做这件事。我选择维护现有的提供商基础设施,同时慢慢地将一个提供商迁移到 Riverpod。

为了完成这项工作,我首先为所有导出的提供程序函数构建了一个重命名垫片。它导入提供程序,并建立 typedef 来为这些名称起别名,使其普遍以“X”结尾,包括 BlockContext 上的扩展名,该扩展名变为 .readX 和 .selectX。我对此进行了测试,一开始没有“X”,然后一次重命名 VSC 中的每个符号,结果出人意料地效果很好。重命名垫片看起来像:

import 'package:provider/provider.dart' as provider;

typedef ProviderX<T> = provider.Provider<T>;
typedef MultiProviderX = provider.MultiProvider;
typedef ChangeNotifierProviderX<T extends ChangeNotifier> = provider.ChangeNotifierProvider<T>;

持续约 100 行。棘手的是扩展:

extension ReadContext on BuildContext {
  T readX<T>() => provider.ReadContext(this).read<T>();
}

extension SelectContext on BuildContext {
  R selectX<T, R>(R Function(T value) selector) => provider.SelectContext(this).select(selector);
}

不可否认,一旦我开始使用该模式,Github 副驾驶就热切地向我提供了一行又一行的内容,并且最初只在一些事情上出错了。

接下来,我将 RiverPod ProviderScope 添加到我的 runApp 中,并选择要迁移的特定提供程序。我在 RiverPod 中创建了等效项,很好地命名了,因为“FooProvider”变成了“fooProvider”,然后在 .readX 或 ConsumerX 访问中找到对该类的所有引用。我插入了与 Consumer 块或 ConsumerWidget 小部件等效的内容,为我提供了一个参考,以便根据需要与 ref.read 或 ref.watch 一起使用。

这不是小事。但是一旦你克服了“伟大的重命名”障碍,剩下的就只是相当机械的翻译,并且可以逐步完成。


1
投票

错误消息表明

ChangeNotifierProvider
不是函数。您正在尝试从
provider
迁移到
Riverpod.

在 Riverpod 中,

ChangeNotifierProvider
的等效类是
ChangeNotifierProvider.autoDispose.

所以你应该替换这一行:

ChangeNotifierProvider(
create: (context) => 
UserProvider(),
),

用这一行:

ChangeNotifierProvider.autoDispose( create: (context) => UserProvider(),),

这应该可以解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.