Map and EDA: retrofit `react-query`'s `useQuery` in place of `usePromise`
bobular opened this issue · 1 comments
I think I have a plan to do this. It's related to the timeslider stepping forward/backward functionality we might still introduce (if the user has a floating plot active). Would appreciate feedback.
Overview
In all our XxxVisualization
plugins, replace
const data = usePromise(useCallback(() => getData(dep1, dep2, dep3), [ dep1, dep2, dep3 ]));
with
const data = useCachedPromise(() => getData(dep1, dep2, dep3), [ dep1, dep2, dep3 ]);
where the return value is exactly the same as before ({ value, error, pending }
);
Implementation
useCachedPromise
would be implemented like this (not tested)
import { useMemo } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { useQuery } from 'react-query';
import { PromiseHookState } from './promise';
export function useCachedPromise<T>(task: () => Promise<T>, deps: any[]): PromiseHookState<T> {
// generate a serialisable key for react-query from a mix of data and class/function dependencies
const uniqueKey = useMemo(() => uuidv4(), deps);
// Using useQuery from react-query with the unique key
const { data, error, isLoading } = useQuery({
queryKey: ['useCachedPromise', uniqueKey],
queryFn: task,
});
// Mapping the state from useQuery to PromiseHookState<T>
const state: PromiseHookState<T> = {
value: data,
pending: isLoading,
error: error,
};
return state;
}
Details
We may want to use isFetching
instead of isLoading
or a combination of it and isLoading
. Or maybe status === 'loading'
. See here. We would need to look into the nitty-gritty of react-query
to make sure we get this right, and consider turning off background refetching? See below.
QueryClientProvider
EDA will need this wrapped too (see packages/libs/eda/src/lib/map/MapVeuContainer.tsx) - at least the VisualizationsContainer
I think we should just have usePromise
use useQuery
. We would have to include QueryClientProvider
in a more centralized place, such as https://github.com/VEuPathDB/web-monorepo/blob/main/packages/libs/wdk-client/src/Core/Root.tsx.