我正在尝试对Flutter中的Dismissible列表项实施撤消,并且在访问BuildContext时遇到问题。
我有一个扑扑的名单,其中的每个项目都是一张卡片。卡被包裹在Dismissible中,这使用户可以滑动以将其解散。 Dismissible会自动从列表中删除该项目。 Dismissible也有一个onDismissed事件-我正在使用此事件来更新Redux状态存储中的项目(将isDismissed标志设置为true),然后显示一个包含UNDO按钮的SnackBar。
这是我遇到问题的地方。我希望UNDO按钮通过将另一个动作调度到Redux存储以将isDismissed设置为false来恢复该项目。为此,我需要一个上下文,从该上下文可以获取商店调度程序。但是,当我尝试下面的代码时,单击UNDO时出现错误:
查找已停用的小部件的祖先是不安全的
class ProductCard extends StatelessWidget {
final Product product;
const ProductCard(this.product);
@override
Widget build(BuildContext context) {
return Dismissible(
key: Key(product.id.toString()),
onDismissed: (direction) {
StoreProvider.of<AppState>(context).dispatch(DismissAction(product));
// Then show a snackbar to allow undo
Scaffold.of(context).showSnackBar(
SnackBar(
content: Row(
children: <Widget>[
Expanded(child: Text("Dismissed ${product.title}"),),
FlatButton(
onPressed: () {
// THIS IS WHERE I GET THE ERROR
StoreProvider.of<AppState>(context).dispatch(UndoDismissAction(product));
},
child: Text("UNDO"),
)
],
)
)
);
},
child: Card(
child: ...
)
);
}
}
从我的阅读中,我认为正在发生的事情是撤消按钮的onPressed动作中的行StoreProvider.of<AppState>(context)
试图使用属于Card的上下文,但是因为该Card已被删除从列表中删除,它不再存在。
我不确定该如何解决。我已经阅读了有关颤振键的信息,并认为答案可能是开始传递某种全局键,但是我无法完全理解它是如何工作的。我试了一下,遇到了'inheritFromWidgetOfExactType' was called on null
的另一个问题。钥匙是否可以解决此问题?如果是这样,我应该在哪里创建密钥,我应该将其传递到小部件中,应该使用哪种类型的密钥等等,或者有更好的解决方案?
非常感谢!
答案 0 :(得分:0)
将商店的单个副本提取到局部变量中,然后该变量将被下面的所有lambda捕获。
@override
Widget build(BuildContext context) {
var store = StoreProvider.of<AppState>(context);
return Dismissible(
...
store.dispatch(DismissAction(product));