feat(infinite-query): add useInfiniteQuery hook with example
This commit is contained in:
@@ -1 +1 @@
|
|||||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.6/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.6/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.4/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.3.1/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/","native_build":true,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.3/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]}],"date_created":"2022-09-14 11:35:53.826188","version":"3.3.0"}
|
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.6/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.6/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.4/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.3.1/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/","native_build":true,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.3/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]}],"date_created":"2022-09-14 13:12:02.969795","version":"3.3.0"}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:fl_query_hooks/fl_query_hooks.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fl_query/fl_query.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
|
final infiniteQueryHookJob = InfiniteQueryJob<Map, void, int>(
|
||||||
|
queryKey: "infinite-posts",
|
||||||
|
initialParam: 1,
|
||||||
|
task: (queryKey, pageParam, externalData) async {
|
||||||
|
return jsonDecode(
|
||||||
|
(await http.get(
|
||||||
|
Uri.parse("https://jsonplaceholder.typicode.com/posts/$pageParam"),
|
||||||
|
))
|
||||||
|
.body,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
getNextPageParam: (lastPage, lastParam) {
|
||||||
|
return lastParam + 1;
|
||||||
|
},
|
||||||
|
getPreviousPageParam: (lastPage, lastParam) {
|
||||||
|
return lastParam - 1;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
class BasicHookInfiniteQueryExample extends HookWidget {
|
||||||
|
const BasicHookInfiniteQueryExample({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final infiniteQuery = useInfiniteQuery(
|
||||||
|
job: infiniteQueryHookJob,
|
||||||
|
externalData: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(),
|
||||||
|
body: Stack(
|
||||||
|
children: [
|
||||||
|
ListView.builder(
|
||||||
|
itemCount: infiniteQuery.pages.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final page = infiniteQuery.pages[index];
|
||||||
|
return ListTile(
|
||||||
|
title: Text(page?["title"] ?? ""),
|
||||||
|
subtitle: Text(page?["body"] ?? ""),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.bottomRight,
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.refresh_rounded),
|
||||||
|
onPressed: () => infiniteQuery.refetchPages(),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.get_app_rounded),
|
||||||
|
onPressed: () => infiniteQuery.fetchNextPage(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fl_query_hooks_example/components/basic_hook_infinite_query.dart';
|
||||||
import 'package:fl_query_hooks_example/components/basic_hook_mutation.dart';
|
import 'package:fl_query_hooks_example/components/basic_hook_mutation.dart';
|
||||||
import 'package:fl_query_hooks_example/components/basic_hook_query.dart';
|
import 'package:fl_query_hooks_example/components/basic_hook_query.dart';
|
||||||
import 'package:fl_query_hooks_example/components/lazy_hook_query.dart';
|
import 'package:fl_query_hooks_example/components/lazy_hook_query.dart';
|
||||||
@@ -49,15 +50,26 @@ class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: const [
|
children: [
|
||||||
BasicHookQueryExample(),
|
const BasicHookQueryExample(),
|
||||||
QueryHookExternalDataExample(),
|
const QueryHookExternalDataExample(),
|
||||||
LazyHookQueryExample(),
|
const LazyHookQueryExample(),
|
||||||
QueryHookVariableKeyExample(),
|
const QueryHookVariableKeyExample(),
|
||||||
QueryHookPreviousDataExample(),
|
const QueryHookPreviousDataExample(),
|
||||||
Divider(),
|
ListTile(
|
||||||
BasicHookMutationExample(),
|
title: const Text("Infinite Query Example"),
|
||||||
MutationHookVariableKeyExample(),
|
trailing: const Icon(Icons.open_in_new),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const BasicHookInfiniteQueryExample(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
const BasicHookMutationExample(),
|
||||||
|
const MutationHookVariableKeyExample(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ library fl_query_hooks;
|
|||||||
|
|
||||||
export 'src/use_query.dart';
|
export 'src/use_query.dart';
|
||||||
export 'src/use_mutation.dart';
|
export 'src/use_mutation.dart';
|
||||||
|
export 'src/use_infinite_query.dart';
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
// ignore_for_file: invalid_use_of_protected_member
|
||||||
|
|
||||||
|
import 'package:fl_query/fl_query.dart';
|
||||||
|
import 'package:fl_query_hooks/src/utils.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
|
||||||
|
InfiniteQuery<T, Outside, PageParam>
|
||||||
|
useInfiniteQuery<T extends Object, Outside, PageParam extends Object>({
|
||||||
|
required InfiniteQueryJob<T, Outside, PageParam> job,
|
||||||
|
required Outside externalData,
|
||||||
|
|
||||||
|
// /// Called when the query returns new data, on query
|
||||||
|
// /// refetch or query gets expired
|
||||||
|
// QueryListener<T>? onData,
|
||||||
|
|
||||||
|
// /// Called when the query returns error
|
||||||
|
// QueryListener<dynamic>? onError,
|
||||||
|
List<Object?>? keys,
|
||||||
|
}) {
|
||||||
|
final context = useContext();
|
||||||
|
final QueryBowl queryBowl = QueryBowl.of(context);
|
||||||
|
final ValueKey<String> uKey = useMemoized(() => ValueKey(uuid.v4()), []);
|
||||||
|
final query = useRef(
|
||||||
|
InfiniteQuery.fromOptions(
|
||||||
|
job,
|
||||||
|
externalData: externalData,
|
||||||
|
queryBowl: queryBowl,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final oldJob = usePrevious(job);
|
||||||
|
final oldExternalData = usePrevious(externalData);
|
||||||
|
// final oldOnData = usePrevious(onData);
|
||||||
|
// final oldOnError = usePrevious(onError);
|
||||||
|
|
||||||
|
final init = useCallback(([T? previousData]) {
|
||||||
|
query.value = queryBowl.addInfiniteQuery<T, Outside, PageParam>(
|
||||||
|
job,
|
||||||
|
externalData: externalData,
|
||||||
|
// previousData: previousData,
|
||||||
|
key: uKey,
|
||||||
|
// onData: onData,
|
||||||
|
// onError: onError,
|
||||||
|
);
|
||||||
|
final hasExternalDataChanged = query.value.externalData != null &&
|
||||||
|
query.value.prevUsedExternalData != null &&
|
||||||
|
!isShallowEqual(
|
||||||
|
query.value.externalData!, query.value.prevUsedExternalData!);
|
||||||
|
if (query.value.fetched && hasExternalDataChanged) {
|
||||||
|
query.value.refetch();
|
||||||
|
} else if (!query.value.fetched) {
|
||||||
|
query.value.fetch();
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
queryBowl,
|
||||||
|
query.value,
|
||||||
|
uKey,
|
||||||
|
job,
|
||||||
|
externalData,
|
||||||
|
// onData,
|
||||||
|
// onError,
|
||||||
|
]);
|
||||||
|
|
||||||
|
final disposeQuery = useCallback(() {
|
||||||
|
query.value.unmount(uKey);
|
||||||
|
// if (onData != null) query.value.removeDataListener(onData);
|
||||||
|
// if (onError != null) query.value.removeErrorListener(onError);
|
||||||
|
}, [
|
||||||
|
query.value,
|
||||||
|
uKey,
|
||||||
|
// onData,
|
||||||
|
// onError,
|
||||||
|
]);
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
init();
|
||||||
|
return disposeQuery;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
// final hasOnErrorChanged = oldOnError != onError && oldOnError != null;
|
||||||
|
// final hasOnDataChanged = oldOnData != onData && oldOnData != null;
|
||||||
|
if (oldJob != null && oldJob.queryKey != job.queryKey) {
|
||||||
|
disposeQuery();
|
||||||
|
init();
|
||||||
|
} else if (oldExternalData != null &&
|
||||||
|
externalData != null &&
|
||||||
|
!isShallowEqual(oldExternalData, externalData)) {
|
||||||
|
if (job.refetchOnExternalDataChange ??
|
||||||
|
queryBowl.refetchOnExternalDataChange) {
|
||||||
|
QueryBowl.of(context).addInfiniteQuery(
|
||||||
|
job,
|
||||||
|
externalData: externalData,
|
||||||
|
key: uKey,
|
||||||
|
// onData: onData,
|
||||||
|
// onError: onError,
|
||||||
|
)..refetchPages();
|
||||||
|
} else {
|
||||||
|
QueryBowl.of(context)
|
||||||
|
.getQuery(job.queryKey)
|
||||||
|
?.setExternalData(externalData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (hasOnDataChanged) query.value.removeDataListener(oldOnData);
|
||||||
|
// if (hasOnErrorChanged) query.value.removeErrorListener(oldOnError);
|
||||||
|
}
|
||||||
|
// else {
|
||||||
|
// if (hasOnDataChanged) {
|
||||||
|
// query.value.removeDataListener(oldOnData);
|
||||||
|
// if (onData != null) query.value.addDataListener(onData);
|
||||||
|
// }
|
||||||
|
// if (hasOnErrorChanged) {
|
||||||
|
// query.value.removeErrorListener(oldOnError);
|
||||||
|
// if (onError != null) query.value.addErrorListener(onError);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return queryBowl.getInfiniteQuery<T, Outside, PageParam>(job.queryKey) ??
|
||||||
|
query.value;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user