fix: state update on unmounted hook and infinite query cache refetch not working

This commit is contained in:
Kingkor Roy Tirtho
2023-02-10 18:52:27 +06:00
parent 02d11d2f46
commit 0af8190cf8
6 changed files with 55 additions and 19 deletions
@@ -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.9/","native_build":true,"dependencies":[]},{"name":"path_provider_ios","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.22/","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":[]},{"name":"path_provider_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/","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":[]},{"name":"path_provider_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/","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":[]},{"name":"path_provider_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/","native_build":false,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/","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":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2022-12-16 21:09:35.483382","version":"3.3.8"}
{"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.9/","native_build":true,"dependencies":[]},{"name":"path_provider_ios","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.22/","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":[]},{"name":"path_provider_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/","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":[]},{"name":"path_provider_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/","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":[]},{"name":"path_provider_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/","native_build":false,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/","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":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2022-12-24 13:10:41.077116","version":"3.3.8"}
@@ -1,12 +1,36 @@
import 'dart:convert';
import 'package:fl_query/fl_query.dart';
import 'package:fl_query_example/components/query_disk_cache.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class Todo {
int? userId;
int? id;
String? title;
bool? completed;
Todo({this.userId, this.id, this.title, this.completed});
Todo.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
id = json['id'];
title = json['title'];
completed = json['completed'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['userId'] = userId;
data['id'] = id;
data['title'] = title;
data['completed'] = completed;
return data;
}
}
final infiniteQueryDiskCacheExampleQuery =
InfiniteQueryJob<List<User>, void, int>(
InfiniteQueryJob<List<Todo>, void, int>(
queryKey: 'infiniteQueryDiskCacheExampleQuery',
initialParam: 0,
getNextPageParam: (lastPage, lastParam) {
@@ -18,11 +42,11 @@ final infiniteQueryDiskCacheExampleQuery =
return firstParam - 5;
},
serialize: (data) {
return jsonEncode(data.map((user) => user.toJson()).toList());
return jsonEncode(data.map((todo) => todo.toJson()).toList());
},
deserialize: (raw) {
return List.from(jsonDecode(raw))
.map((user) => User.fromJson(user))
.map((todo) => Todo.fromJson(todo))
.toList();
},
serializePageParam: (param) => param.toString(),
@@ -30,10 +54,10 @@ final infiniteQueryDiskCacheExampleQuery =
task: (_, pageParam, __) async {
final res = await http.get(
Uri.parse(
"https://jsonplaceholder.typicode.com/users?_start=$pageParam&_end=${pageParam + 5}"),
"https://jsonplaceholder.typicode.com/todos?_start=$pageParam&_end=${pageParam + 5}"),
);
final body = List.from(jsonDecode(res.body))
.map((user) => User.fromJson(user))
.map((todo) => Todo.fromJson(todo))
.toList()
..shuffle();
if (pageParam == 0) await Future.delayed(const Duration(seconds: 5));
@@ -62,12 +86,12 @@ class _InfiniteQueryDiskCacheExampleState
return Scaffold(
appBar: AppBar(
title: const Text("Infinite Query Disk Cache Example")),
body: InfiniteQueryBuilder<List<User>, void, int>(
body: InfiniteQueryBuilder<List<Todo>, void, int>(
job: infiniteQueryDiskCacheExampleQuery,
externalData: null,
builder: (context, query) {
final data = query.pages
.expand((page) => page?.toList() ?? [])
.expand((page) => page?.toList() ?? <Todo>[])
.toList();
return Scaffold(
floatingActionButton: FloatingActionButton(
@@ -81,9 +105,12 @@ class _InfiniteQueryDiskCacheExampleState
body: ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(data[index].name!),
subtitle: Text(data[index].email!),
return CheckboxListTile(
value: data[index].completed == true,
title: Text(data[index].title ?? ""),
dense: true,
secondary: Text(data[index].id.toString()),
onChanged: null,
);
},
),
+4 -4
View File
@@ -195,13 +195,13 @@ abstract class BaseQuery<T extends Object, Outside, Error>
notifyListeners();
return data;
}
final x = hasData && !isPreviousData;
var isOnline = await isNetworkOnline;
/// if isLoading/isRefetching is true that means its already fetching/
/// refetching. So [_execute] again can create a race condition
if (isLoading ||
isRefetching ||
!(await isNetworkOnline) ||
(hasData && !isPreviousData)) return data;
if (isLoading || isRefetching || !isOnline || (hasData && !isPreviousData))
return data;
status = QueryStatus.loading;
notifyListeners();
return execute().then((_) {
@@ -45,12 +45,14 @@ class _InfiniteQueryBuilderState<T extends Object, Outside,
WidgetsBinding.instance.addPostFrameCallback((_) {
init();
QueryBowl.of(context).onInfiniteQueriesUpdate<T, Outside, PageParam>(
(infiniteQuery) {
(infiniteQuery) async {
if (infiniteQuery.queryKey != widget.job.queryKey) return;
if (mounted)
setState(() {
this.infiniteQuery = infiniteQuery;
});
if (infiniteQuery.isCachedData && !infiniteQuery.fetched)
await infiniteQuery.refetchPages();
},
);
});
@@ -83,9 +83,13 @@ InfiniteQuery<T, Outside, PageParam>
WidgetsBinding.instance.addPostFrameCallback((_) {
init();
QueryBowl.of(context).onInfiniteQueriesUpdate<T, Outside, PageParam>(
(newInfiniteQuery) {
(newInfiniteQuery) async {
if (newInfiniteQuery.queryKey != job.queryKey || !mounted()) return;
infiniteQuery.value = newInfiniteQuery;
if (!infiniteQuery.value.fetched &&
infiniteQuery.value.isCachedData) {
await infiniteQuery.value.refetchPages();
}
update();
},
);
+4 -1
View File
@@ -11,5 +11,8 @@ const uuid = Uuid();
useForceUpdate() {
final state = useState(false);
return () => state.value = !state.value;
final isMounted = useIsMounted();
return () {
if (isMounted()) state.value = !state.value;
};
}