Reputation: 108
I have a button that uses a counter provider with Riverpod, I would like to add a local state isLoading
to the button.
While I can do it all inside the build
method, I'm wondering if there is a way to lift the state to the instance level so that other methods inside the Btn
class can also access this state, for instance, making onPressed
function into another method.
The code with everything inside build
:
class Btn extends HookConsumerWidget {
const Btn({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final isLoading = useState(false);
final counter = ref.watch(counterProvider);
final counterNotifier = ref.read(counterProvider.notifier);
useEffect(() {
if (isLoading.value) {
Future.delayed(const Duration(seconds: 1), () {
isLoading.value = false;
counterNotifier.reset();
});
}
return null;
}, [isLoading.value]);
return ElevatedButton.icon(
onPressed: () => isLoading.value = true : null,
icon: isLoading.value ? const CircularProgressIndicator() : Container(),
label:Text(isLoading.value ? "Loading" : "$counter"),
);
}
}
I would like to turn it into:
class Btn extends HookConsumerWidget {
const Btn({super.key});
// declare isLoading
void onPressed() {
isLoading.value = true;
}
@override
Widget build(BuildContext context, WidgetRef ref) {
final counter = ref.watch(counterProvider);
final counterNotifier = ref.read(counterProvider.notifier);
useEffect(() {
if (isLoading.value) {
Future.delayed(const Duration(seconds: 1), () {
isLoading.value = false;
counterNotifier.reset();
});
}
return null;
}, [isLoading.value]);
return ElevatedButton.icon(
onPressed: onPressed,
icon: isLoading.value ? const CircularProgressIndicator() : Container(),
label: Text(isLoading.value ? "Loading" : "$counter"),
);
}
}
Upvotes: 2
Views: 61
Reputation: 4844
You can turn your class into a ConsumerStatefullWidget
and discard the hooks, then all your parameters can become class fields.
Furthermore, try not to pull logic into the widget. There is business logic, then place it in a notifier class (and even use an AsyncNotifier
that contains "sealed" state with data, load and error). If it's ui logic, it's not a bad option to place it in the presenter classes.
All of this will increase code reusability and allow each layer of your application to clearly fulfill its responsibilities.
Upvotes: 0