Skip to main content

Loading state principals

When a component displays data that is coming from an EVA service, we always have to deal with loading states, as the data could be either stale or unavailable.

Since we also use service response caching, we have two states that tell us the loading state of the service

  • the response of the service (either undefined or the service response)
  • the isLoading state of the service state (boolean)
Loading statesresponse === undefinedresponse !== undefined
isLoadingService is loading without previous response
LoadingStateBox
Service is loading with previous response
ProgressBar on Card
!isLoadingNo response
Call the service
Service response is loaded
Display the data

There are two loading states that we are differentiating, and we display these states in different ways:

  • when the service is loading, and there is no cached response from a previous call (the response of the service is undefined)
  • when the service is loading, and there is a cached response from a previous call (the response of the service is not undefined)

In code we can determine these states as follows:

import { hooks } from '@springtree/eva-sdk-react-recoil';import { useSetRequest } from '@springtreesolutions/eva-suite-react-hooks';import { exampleServiceState } from 'store/example-service';
const Example = () => {  const serviceResponse = hooks.useGetServiceResponse(exampleServiceState);  const serviceIsLoading = hooks.useIsServiceLoading({    serviceState: exampleServiceState,  });
  const serviceIsLoadingWithoutPreviousResponse = useMemo(    () => serviceIsLoading && !serviceResponse,    [serviceIsLoading, serviceResponse],  );
  const serviceIsLoadingWithPreviousResponse = useMemo(    () => serviceIsLoading && serviceResponse,    [serviceIsLoading, serviceResponse],  );
  return (/* See next section for rendering these states */);};
export default Example;

Service loading without a current service response available#

In this case we have no previous data to display, so we display a LoadingStateBox component in a Card.

import { Card, LoadingStateBox } from '@springtree/eva-suite-ui';
// ...
const Example = () => {  //...  if (serviceIsLoadingWithoutPreviousResponse) {    return (      <Card>        <LoadingStateBox limit={3} />      </Card>    );  }  // ...}

Service loading with a current service response available#

In this case we have stale data to display from the previous service call. We display this data, and we also notify the user that new data is fetching in the background, via a ProgressBar on the Card.

import { Box, Card, ProgressBar, RelativeBox } from '@springtree/eva-suite-ui';
// ...
const Example = () => {  //...  return (    <Card>      <RelativeBox>        <ProgressBar loading={serviceIsLoadingWithPreviousResponse}>        <Box>          {/* Display data */}        </Box>      </RelativeBox>    </Card>  );}
// ...

Putting it all together#

/src/components/Example.tsx
import {  Box,  Card,  ProgressBar,  RelativeBox,  LoadingStateBox,} from '@springtree/eva-suite-ui';import { hooks } from '@springtree/eva-sdk-react-recoil';import { useSetRequest } from '@springtreesolutions/eva-suite-react-hooks';import { exampleServiceState } from 'store/example-service';
const Example = () => {  const serviceResponse = hooks.useGetServiceResponse(exampleServiceState);  const serviceIsLoading = hooks.useIsServiceLoading({    serviceState: exampleServiceState,  });
  const serviceIsLoadingWithoutPreviousResponse = useMemo(    () => serviceIsLoading && !serviceResponse,    [serviceIsLoading, serviceResponse],  );
  const serviceIsLoadingWithPreviousResponse = useMemo(    () => serviceIsLoading && serviceResponse,    [serviceIsLoading, serviceResponse],  );
  return (    <Card>      {serviceIsLoadingWithoutPreviousResponse ? (        <LoadingStateBox limit={3} />      ) : (        <RelativeBox>          <ProgressBar loading={serviceIsLoadingWithPreviousResponse}>          <Box>            {/* Display data */}          </Box>        </RelativeBox>      )}    </Card>  );};
export default Example;