我正在使用MultiProvider
,但出现此错误:
Unhandled Exception: A Products was used after being disposed. Once you have called dispose() on a Products, it can no longer be used.
这是我的主.dart文件。这种结构有什么问题?
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: Auth(),
),
ChangeNotifierProxyProvider<Auth, Products>(
update: (ctx, auth, previousProducts) => Products(
auth.token,
auth.userId,
previousProducts == null ? [] : previousProducts.items,
),
),
ChangeNotifierProvider.value(
value: Cart(),
),
ChangeNotifierProxyProvider<Auth, Orders>(
update: (ctx, auth, previousOrders) => Orders(
auth.token,
auth.userId,
previousOrders == null ? [] : previousOrders.orders,
),
),
],
child: Consumer<Auth>(
builder: (ctx, auth, _) => MaterialApp(
title: 'MyShop',
theme: ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.deepOrange,
fontFamily: 'Lato',
),
home: auth.isAuth
? ProductOverviewScreen()
: FutureBuilder(
future: auth.tryAutoLogin(),
builder: (ctx, authResultSnapshot) =>
authResultSnapshot.connectionState ==
ConnectionState.waiting
? SplashScreen()
: AuthScreen(),
),
routes: {
ProductDetailScreen.routeName: (ctx) => ProductDetailScreen(),
CartScreen.routeName: (ctx) => CartScreen(),
OrdersScreen.routeName: (ctx) => OrdersScreen(),
UserProductsScreen.routeName: (ctx) => UserProductsScreen(),
EditProductsScreen.routeName: (ctx) => EditProductsScreen(),
},
),
),
);
}
}
use yourProvider.value 而不是创建
itemBuilder: (ctx, index) => ChangeNotifierProvider.value(
value: products[index],
child: ProductItem(),
),
itemCount: products.length,
);
我也遇到了同样的错误,我通过以下方式解决了它:
ChangeNotifierProvider<"Provider name">.value(value:<PassedValue>);
似乎 ChangeNotifierProvider创建了一个提供程序的实例,当它的工作完成时,dispose(( 方法被调用,因此,该实例被 ChangeNotifierProvider.value 清除,事实并非如此,我们能够重用之前创建的实例。
以下是官方文档: https://pub.dev/packages/provider
这就是您可以修复它的方法
GridView.builder(
padding: const EdgeInsets.all(10),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemBuilder: ((context, i) => ChangeNotifierProvider.value( // <--
value: productsItems[i],
child: ProductItem(),
)),
itemCount: productsItems.length,
);
}
在产品概述屏幕中为产品提供程序添加延迟;
@override
void initState() {
Future.delayed(Duration(seconds: 1)).then((_) {
Provider.of<Products>(context, listen: false).fetchAndSetProducts();
});
super.initState();
}
例如,这样做:
return MaterialPageRoute(
builder: (_) => ChangeNotifierProvider<EntryPermitViewModel>.value(
value: EntryPermitViewModel(),
child: const EntryPermitScreen(),
),
);
我认为您必须将产品提供程序添加到提供程序:[] 上面的代理提供程序作为身份验证提供程序的定义,如下所示:
providers: [
ChangeNotifierProvider<Auth>.value(
value: Auth(),
ChangeNotifierProvider<Products>.value(
value: Products(),
ChangeNotifierProxyProvider<Auth, Products>(
update: (ctx, auth, previousProducts) => Products(
auth.token,
auth.userId,
previousProducts == null ? [] : previousProducts.items,
),
),
ChangeNotifierProvider<Cart>.value(
value: Cart(),
),
ChangeNotifierProxyProvider<Auth, Orders>(
update: (ctx, auth, previousOrders) => Orders(
auth.token,
auth.userId,
previousOrders == null ? [] : previousOrders.orders,
),
),
],
使用
Navigator.of(context).pushNamed('/');
在你的抽屉里,你打电话给logout
. 这将解决这个问题 谢谢。。