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 the ItemsList class, I thought that changing the statement state = [...state, item] to state.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]; to void 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.