Reducing boilerplate for Side Effect operations #3572
-
I was reading through this section in the docs and I implemented it in my own app. I searched the internet and GitHub issues and discussions for a way to reduce boilerplate for the following:
After finding no official recommendations for the second point, or an example in the docs showing how to display SnackBar on side effect completion, I decided to write a custom hook. SideEffectController<T> useSideEffect<T>() {
var future = useState<Future<T>?>(null);
var snapshot = useFuture(future.value);
return SideEffectController(
future: future,
snapshot: snapshot,
);
}
class SideEffectController<T> {
ValueNotifier<Future<T>?> future;
final AsyncSnapshot<T> snapshot;
FutureOr<dynamic> Function(T)? onChanged;
SideEffectController({
required this.future,
required this.snapshot,
this.onChanged,
});
set value(Future<T> fut) {
future.value = fut;
if (onChanged case var cb?) future.value?.then(cb);
}
bool isLoading() {
return snapshot.connectionState == ConnectionState.waiting;
}
void listen(FutureOr<dynamic> Function(T)? cb) {
onChanged = cb;
}
} I use it in the build method as follows: class EditProfilePage extends HookConsumerWidget {
const EditProfilePage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
var profileProv = ref.watch(profileProvider);
var sideEffect = useSideEffect();
sideEffect.listen((snapshot) => switch (snapshot) {
AsyncSnapshot(:var error?) => context.showSnackBar('Error!'),
_ => context.showSnackBar('Success!'),
});
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(30.0),
child: switch (profileProv) {
AsyncData(value: var user) => ProfileForm(
user: user,
onSubmit: (patch) => sideEffect.value = ref
.read(profileProvider.notifier)
.patch(UserPatchModel(update: patch)),
isSubmitting: sideEffect.isLoading(),
),
AsyncError() => const Text('Could not fetch profile'),
_ => const CircularProgressIndicator(),
},
),
);
}
} This seems to work, but since I am new to riverpod, there has to be at least one issue with this code. I'd like to ask whether:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
The usual approach would be to use |
Beta Was this translation helpful? Give feedback.
-
That's alright. It's just that may people don't use hooks. But in itself there's no real issue I can see so far. |
Beta Was this translation helpful? Give feedback.
That's alright. It's just that may people don't use hooks. But in itself there's no real issue I can see so far.