Closed selegiline closed 3 years ago
final counterProvider = StateNotifierProvider<Counter, int>((_) => Counter());
class Counter extends StateNotifier<int> {
Counter() : super(0);
void increment() => state++;
}
class UseStateExample extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
print('build');
return Scaffold(
appBar: AppBar(
title: const Text('Riverpod counter example'),
),
body: Center(
child: HookBuilder(
builder: (context) {
final count = ref.watch(counterProvider);
return Text(
'$count',
style: Theme.of(context).textTheme.headline4,
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => ref.read(counterProvider.notifier).increment(),
child: const Icon(Icons.add),
),
);
}
}
another sample as the riverpod document
Hello,
This is the expected behavior, as I know.
@selegiline You could use useValueNotifier
instead of useState
because it doesn't trigger a rebuild and combine it with listening to the ValueNotifier near the Text widget (HookBuilder or a different Hook widget required).
In any case, if you are doing this too much, that's where provider or riverpod shine.
class UseStateExample extends HookWidget {
@override
Widget build(BuildContext context) {
final counterVN = useValueNotifier(0);
print("UseStateExample build");
return Scaffold(
appBar: AppBar(
title: const Text('useState example'),
),
body: Center(
child: HookBuilder(
builder: (_) {
final counter = useValueListenable(counterVN);
return Text('Button tapped ${counter} times');
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => counterVN.value++,
child: const Icon(Icons.add),
),
);
}
}
Indeed this is the expected behavior, and David's example is correct.
Although I would argue that the gain is so minimal that I would prefer the more readable option.