swrv icon indicating copy to clipboard operation
swrv copied to clipboard

(Feature Request) Return State explicitly

Open jacobgoh101 opened this issue 4 years ago • 3 comments

react-query's useQuery return states explicitly.

The result object contains a few very important states you'll need to be aware of to be productive. A query can only be in one of the following states at any given moment:

isLoading or status === 'loading' - The query has no data and is currently fetching isError or status === 'error' - The query encountered an error isSuccess or status === 'success' - The query was successful and data is available isIdle or status === 'idle' - The query is currently disabled (you'll learn more about this in a bit)

This is what I am doing currently to achieve similar results.

import useSWRV from 'swrv';
import { fetcherFn, IConfig, IKey } from 'swrv/dist/types';
import { computed, Ref, ref, watchEffect } from '@vue/composition-api';

export function useSwrvExtra<Data>(
  key: IKey,
  fn?: fetcherFn<Data>,
  config?: IConfig
) {
  const { data, error, isValidating, mutate } = useSWRV(key, fn, config);
  const { state, STATES } = useSwrvState(data, error, isValidating);
  return {
    data,
    error,
    isValidating,
    mutate,
    isStaleIfError: computed(() => state.value === STATES.STALE_IF_ERROR),
    isPending: computed(() => state.value === STATES.PENDING),
    isSuccess: computed(() => state.value === STATES.SUCCESS),
    isErrored: computed(() => state.value === STATES.ERROR),
  };
}

const STATES = {
  VALIDATING: 'VALIDATING',
  PENDING: 'PENDING',
  SUCCESS: 'SUCCESS',
  ERROR: 'ERROR',
  STALE_IF_ERROR: 'STALE_IF_ERROR',
};

function useSwrvState<Data>(
  data: Ref<Data>,
  error: Ref<any>,
  isValidating: Ref<boolean>
) {
  const state = ref('idle');
  watchEffect(() => {
    if (data.value && isValidating.value) {
      state.value = STATES.VALIDATING;
      return;
    }
    if (data.value && error.value) {
      state.value = STATES.STALE_IF_ERROR;
      return;
    }
    if (data.value === undefined && !error.value) {
      state.value = STATES.PENDING;
      return;
    }
    if (data.value && !error.value) {
      state.value = STATES.SUCCESS;
      return;
    }
    if (data.value === undefined && error) {
      state.value = STATES.ERROR;
      return;
    }
  });

  return {
    state,
    STATES,
  };
}

Usage:

  const {  data, error, isValidating, isSuccess } = useSwrvExtra(
           //....
  );

why not add this feature to the core library instead ?

jacobgoh101 avatar Mar 21 '21 13:03 jacobgoh101

@jacobgoh101 we are also talking about this on https://github.com/vercel/swr/issues/141. Once that is decided, we can implement the feature.

darrenjennings avatar Mar 22 '21 02:03 darrenjennings

@darrenjennings any updates?

sebastienlabine avatar May 13 '21 18:05 sebastienlabine

As an alternative, I am using vue-query instead of srwv now.

jacobgoh101 avatar May 21 '21 17:05 jacobgoh101