新版Flutter中如何升级ChangeNotifierProxyProvider旧代码并解决报错
解决方案
报错原因
你遇到的报错是因为新版Provider的ChangeNotifierProxyProvider强制要求实现create方法用于状态初始化,而你的Products类仅声明了需要3个位置参数的构造函数,无默认无参构造函数,直接调用Products()自然会触发参数不足的错误。
正确修改方案
方案1:直接兼容原有构造函数(无需修改Products类)
初始化阶段传入占位值即可,update方法会在依赖的Auth实例准备完成后立刻执行,替换掉初始的占位实例:
void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MultiProvider( providers: [ // 建议这里替换成普通create写法,.value仅适合复用已有实例的场景 ChangeNotifierProvider(create: (ctx) => Auth()), ChangeNotifierProxyProvider<Auth, Products>( create: (ctx) => Products('', '', []), update: (ctx, auth, previousProducts) => Products( auth.token as String, auth.userId as String, previousProducts == null ? [] : previousProducts.items, ), ), // 其余Provider保持不变 ], // 其余代码保持不变 ); } }
方案2:优化写法(推荐,避免重复创建实例)
你可以修改Products类的构造函数为可选参数,同时在update阶段复用已有实例,减少性能损耗:
- 先修改Products类定义:
class Products extends ChangeNotifier { String? authToken; String? userId; List items = []; // 改为可选命名参数,配置默认值 Products({this.authToken, this.userId, this.items = const []}); // 原有其余逻辑保持不变 }
- 再修改ProxyProvider配置:
ChangeNotifierProxyProvider<Auth, Products>( create: (ctx) => Products(), update: (ctx, auth, previousProducts) { // 复用已有实例,修改属性后直接返回,无需重复创建 previousProducts?.authToken = auth.token; previousProducts?.userId = auth.userId; return previousProducts ?? Products( authToken: auth.token as String, userId: auth.userId as String, ); }, )
额外注意事项
- 如果你需要兼容空安全,建议给
Auth类的token和userId添加非空判断,避免强制类型转换as String可能带来的崩溃问题 ChangeNotifierProvider.value仅适合你需要复用已经创建好的ChangeNotifier实例的场景,新创建的实例直接用ChangeNotifierProvider(create: ...)写法即可
内容的提问来源于stack exchange,提问作者user11874694
相关产品推荐
相关产品推荐

