VEuPathDB / web-monorepo

A monorepo that contains all frontend code for VEuPathDB websites
Apache License 2.0
2 stars 0 forks source link

Map and EDA: retrofit `react-query`'s `useQuery` in place of `usePromise` #1103

Open bobular opened 4 months ago

bobular commented 4 months ago

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

dmfalke commented 4 months ago

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.