[Flutter/dart] Support item deletion with Redux pattern
Background
Consider the following case.
There is a list of items
There is a page that displays details for a specific item.
You can delete the item on the details page.
After deleting, return to other pages (list page, etc.)
I think this is a common pattern in apps.
Issue
If you are using the redux pattern, or more specifically if you are managing the state with a Provider, you probably have a configuration like below.
The entire app is a child of StoreProvider, and when the contents of the store change, the entire app will be rebuilt.
The item details page extracts the item from the store using the StoreConnector.
When deleting an item on the item details page, move to the specified page
//move to item details page
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context)=> StoreConnector<AppState, ItemDetailViewModel>(
converter: (store)
=> ItemDetailViewModel.create(store, itemId),
//2 extract item from store
builder: (context, model) {
return ItemDetailPage(model); //item details page
},
)
)
);
Widget _itemDeleteButton(){
return GestureDetector(
child: const Icon(Icons.delete),
onTap: ()async{
await _deleteItem();
await Navigator.of(context).push(
//3 move to other page
);
}
}
In this case, the following issues arise:
StoreProvider rebuilds the entire app when an item is deleted
The details page creation process will also be executed again.
In other words, "function to extract the specified item from the store" (2) is also executed again.
Since that item no longer exists, it will throw an exception.
Of course, if the exit from the details page is ealier than the process in step 2, this problem will not occur (since the details page is no longer displayed, the page creation process will not run).
However, since the rebuild by StoreProvider runs asynchronously with the processing on the details page, we cannot guarantee that you will be able to exit first.
Solution
In process 2, if the specified item does not exist in the store, return null.
In the item extraction process by StoreConnector, if the return value of the converter is null, move to another separately prepared page (such as displaying "This item has been deleted")
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context)=> StoreConnector<AppState, ItemDetailViewModel?>(
converter: (store) =>
ItemDetailViewModel.create(store, itemId),
builder: (context, model) {
if(model == null){
return ItemDeletedPage();
//"This item has been deleted" is displayed
}
return ItemDetailPage(model);
},
)
)
);
Lastly
I don't feel like it's a fundamental solution, but I think it can't be helped that there will be some restrictions on the design when using a platform.
When using a provider, not just redux, the page may be rebuilt at unexpected and uncontrollable timing, so you need to be careful.
In fact, it's my fault that I didn't handle exceptions because I thought, ``There's no chance to extract deleted items,'' lol.
Recent Posts
See AllWhat want to do I want to create an input form using TextField. For example, if the input content is a monetary amount, I would like to...
What want to do There is a variable that remain unchanged once the initial value is determined. However, it cannot be determined yet when...
What want to do As the title suggests. Place two widgets in one line on the screen One in the center of the screen and the other on the...
Comments