Skip to content

Instantly share code, notes, and snippets.

@u1aryz
Last active February 21, 2022 07:44
Show Gist options
  • Save u1aryz/694fbbfa6f1530ce861272919f245020 to your computer and use it in GitHub Desktop.
Save u1aryz/694fbbfa6f1530ce861272919f245020 to your computer and use it in GitHub Desktop.
Flutter hooks that runs future at any time (react-use inspiration)
import 'package:flutter/widgets.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
typedef FunctionReturning0<T> = Future<T> Function();
typedef FunctionReturning1<T, S> = Future<T> Function(S arg);
typedef FunctionReturning2<T, S1, S2> = Future<T> Function(S1 arg1, S2 arg2);
typedef FunctionReturning3<T, S1, S2, S3> = Future<T> Function(
S1 arg1, S2 arg2, S3 arg3);
class FutureFnState0<T> {
final FunctionReturning0<T> callback;
final AsyncSnapshot<T> snapshot;
const FutureFnState0(this.callback, this.snapshot);
}
class FutureFnState1<T, S> {
final FunctionReturning1<T, S> callback;
final AsyncSnapshot<T> snapshot;
const FutureFnState1(this.callback, this.snapshot);
}
class FutureFnState2<T, S1, S2> {
final FunctionReturning2<T, S1, S2> callback;
final AsyncSnapshot<T> snapshot;
const FutureFnState2(this.callback, this.snapshot);
}
class FutureFnState3<T, S1, S2, S3> {
final FunctionReturning3<T, S1, S2, S3> callback;
final AsyncSnapshot<T> snapshot;
const FutureFnState3(this.callback, this.snapshot);
}
FutureFnState0<T> useFutureFn0<T>(
FunctionReturning0<T> fn, {
List<Object> keys = const <Object>[],
}) {
final lastCallId = useRef(0);
final snapshot = useState<AsyncSnapshot<T>>(const AsyncSnapshot.nothing());
final callback = useCallback(() {
final callId = ++lastCallId.value;
if (snapshot.value.connectionState != ConnectionState.waiting) {
snapshot.value = const AsyncSnapshot.waiting();
}
final future = fn().then((value) {
if (callId == lastCallId.value) {
snapshot.value = AsyncSnapshot.withData(ConnectionState.done, value);
}
return value;
}).catchError((error) {
if (callId == lastCallId.value) {
snapshot.value = AsyncSnapshot.withError(ConnectionState.done, error);
}
throw error;
});
return future;
}, keys);
return FutureFnState0(callback, snapshot.value);
}
FutureFnState1<T, S> useFutureFn1<T, S>(
FunctionReturning1<T, S> fn, {
List<Object> keys = const <Object>[],
}) {
final lastCallId = useRef(0);
final snapshot = useState<AsyncSnapshot<T>>(const AsyncSnapshot.nothing());
final callback = useCallback((arg) {
final callId = ++lastCallId.value;
if (snapshot.value.connectionState != ConnectionState.waiting) {
snapshot.value = const AsyncSnapshot.waiting();
}
final future = fn(arg).then((value) {
if (callId == lastCallId.value) {
snapshot.value = AsyncSnapshot.withData(ConnectionState.done, value);
}
return value;
}).catchError((error) {
if (callId == lastCallId.value) {
snapshot.value = AsyncSnapshot.withError(ConnectionState.done, error);
}
throw error;
});
return future;
}, keys);
return FutureFnState1(callback, snapshot.value);
}
FutureFnState2<T, S1, S2> useFutureFn2<T, S1, S2>(
FunctionReturning2<T, S1, S2> fn, {
List<Object> keys = const <Object>[],
}) {
final lastCallId = useRef(0);
final snapshot = useState<AsyncSnapshot<T>>(const AsyncSnapshot.nothing());
final callback = useCallback((arg1, arg2) {
final callId = ++lastCallId.value;
if (snapshot.value.connectionState != ConnectionState.waiting) {
snapshot.value = const AsyncSnapshot.waiting();
}
final future = fn(arg1, arg2).then((value) {
if (callId == lastCallId.value) {
snapshot.value = AsyncSnapshot.withData(ConnectionState.done, value);
}
return value;
}).catchError((error) {
if (callId == lastCallId.value) {
snapshot.value = AsyncSnapshot.withError(ConnectionState.done, error);
}
throw error;
});
return future;
}, keys);
return FutureFnState2(callback, snapshot.value);
}
FutureFnState3<T, S1, S2, S3> useFutureFn3<T, S1, S2, S3>(
FunctionReturning3<T, S1, S2, S3> fn, {
List<Object> keys = const <Object>[],
}) {
final lastCallId = useRef(0);
final snapshot = useState<AsyncSnapshot<T>>(const AsyncSnapshot.nothing());
final callback = useCallback((arg1, arg2, arg3) {
final callId = ++lastCallId.value;
if (snapshot.value.connectionState != ConnectionState.waiting) {
snapshot.value = const AsyncSnapshot.waiting();
}
final future = fn(arg1, arg2, arg3).then((value) {
if (callId == lastCallId.value) {
snapshot.value = AsyncSnapshot.withData(ConnectionState.done, value);
}
return value;
}).catchError((error) {
if (callId == lastCallId.value) {
snapshot.value = AsyncSnapshot.withError(ConnectionState.done, error);
}
throw error;
});
return future;
}, keys);
return FutureFnState3(callback, snapshot.value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment