我收到此错误:
“ChangeNotifierProvider”不是一个函数。尝试将名称更正为 匹配现有函数,或定义名为的方法或函数 'ChangeNotifierProvider'
我正在寻求将提供商迁移到 Riverpod,但对我来说很难做到这一点
这是我的代码:
void main() async {
await Hive.initFlutter();
await Hive.openBox("Habit_Database");
runApp(MultiProvider(providers: [
ChangeNotifierProvider(
create: (context) => UserProvider(),
),
], child: const MyApp()));
}
如何解决这个问题?
感谢您提供的任何帮助
我现在正在为客户做这件事。我选择维护现有的提供商基础设施,同时慢慢地将一个提供商迁移到 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 一起使用。
这不是小事。但是一旦你克服了“伟大的重命名”障碍,剩下的就只是相当机械的翻译,并且可以逐步完成。
错误消息表明
ChangeNotifierProvider
不是函数。您正在尝试从 provider
迁移到 Riverpod.
在 Riverpod 中,
ChangeNotifierProvider
的等效类是 ChangeNotifierProvider.autoDispose.
所以你应该替换这一行:
ChangeNotifierProvider(
create: (context) =>
UserProvider(),
),
用这一行:
ChangeNotifierProvider.autoDispose( create: (context) => UserProvider(),),
这应该可以解决问题。
请参阅 Riverpod 的官方文档,他们现在已使用适当的文档更新了其网站,其中包含有关从 Provider 迁移到 Riverpod 的所有详细信息。希望有帮助