Difference between List.add and manually adding item to a Riverpod StateNotifier<List<String>>
The state must change in a way that oldValue == newValue
is false. And by default, adding elements to a list with .add
mutates the list in place, so equality is preserved. That's why's all the examples have something like state = [...state, foo]
, so that an entirely new list is in state, and that's not equal to the old list.
Comments
-
Giorgio over 1 year
I'd like to learn how to use Riverpod, so to this end I'm implementing a small app that shows a list of items and a button that adds a dummy item to the list when tapped.
Problem context
Pressing the button in the following app works as expected (a dummy item is added, and the change is immediately reflected in the UI):
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; void main() => runApp(const ProviderScope(child: MyApp())); class MyApp extends StatelessWidget { const MyApp({Key key}) : super(key: key); @override Widget build(BuildContext context) => MaterialApp(home: HomePage()); } final itemsProvider = StateNotifierProvider((ref) => ItemsList()); class ItemsList extends StateNotifier<List<String>> { ItemsList([List<String> items]) : super(items ?? []); void add(String item) => state = [...state, item]; } class HomePage extends ConsumerWidget { const HomePage({Key key}) : super(key: key); @override Widget build(BuildContext context, ScopedReader watch) { final items = watch(itemsProvider.state); return Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: items.map((e) => Text(e)).toList(), ), floatingActionButton: FloatingActionButton( onPressed: () => context.read(itemsProvider).add('Other item'), tooltip: 'Add item', child: Icon(Icons.add), ), ); } }
Problem
Inside the
add
method of theItemsList
class, I thought that changing the statementstate = [...state, item]
tostate.add(item)
would not make any difference. However, doing so makes the app not responsive to state changes anymore: tapping the button doesn't trigger a change to the UI, and I don't see any new item in the UI until I hot-reload my app.So just to be clear: changing
void add(String item) => state = [...state, item];
tovoid add(String item) => state.add(item);
breaks the link between app state and UI.Why is manually adding an item with list destructuring different from using
List.add
? Thank you very much in advance. -
Amine LAHRIM over 2 yearsit's should be something like .refresh() in case there is a very big list will copy into next each time is not optimal for performance, hope in future this gets fixed