Skip to content

Latest commit

 

History

History
101 lines (79 loc) · 3.29 KB

README.md

File metadata and controls

101 lines (79 loc) · 3.29 KB

React Async Renderer

Quality Gate Status

Utilities for rendering JSX with respect to one or more asynchronous operations.

Installation

npm install --save @mfbtech/react-async-renderer

Usage

At the core of this package is createAsyncRenderer, which renders specific JSX for a given asynchronous operation.

function useMyData() {
  // Setup status state to reflect the state of your long running process
  const [status, setStatus] = useState<AsyncRequestStatus>(AsyncRequestStatusEnum.INIT)
  // Setup error state for any errors associated with your long running process
  const [error, setError] = useState<null | string>(null)
  // Setup data state for any data returned from your long running process
  const [data, setData] = useState<null | string>(null)

  // Logic to kick off a request for data and update local state respectively...

  return {
    status,
    error,
    data
  }
}

function MyDataComponent() {
  const myData = useMyData()
  // Create a renderer for your long running process
  const loadingRenderer = createAsyncRenderer({
    status: myData.status,
    error: myData.error,
    onCompletedSuccessfullyArgs: myData.data
  })

  return loadingRenderer(
    // Render the component with the validated data
    myValidatedData => (
      <div>
        <h1>My Data</h1>
        {myValidatedData}
      </div>
    ), 
    // Optional args that specify UI for specific states in the async operation
    {
      onCompletedWithError: <p>An error has occurred while fetching the data.</p>,
      onLoading: <p>Data is loading...</p>
      onInit: <p>Waiting for the data to be requested.</p>
  })
}

You can also use the AsyncUiModel with createAsyncUiModelRenderer and composeAsyncUiModel to simplify the code used in the consumer component.

function useMyDataComponentUiModel() {
  const myData = useMyData()
  return composeAsyncUiModel(
    myData.data,
    myData.status,
    myData.error ?? ""
  )
}

function MyDataComponent() {
  const uiModel = useMyDataComponentUiModel()
  const loadingRenderer = createAsyncUiModelRenderer(uiModel)

  return loadingRenderer(
    myValidatedData => (
      <div>
        <h1>My Data</h1>
        {myValidatedData}
      </div>
  ))
}

These other utility functions can be used to simplify the logic around createAsyncRenderer:

  • rtkqResultsToStatusError: Used specifically for converting RTK Query Results to an asynchronous request object that can be used with createAsyncRenderer.
  • getCascadedAsyncState: Reduces a chain of asynchronous request objects down one asynchronous request object.
  • getOptimisticAsyncLoadState: Converts its arguments into an optimistic asynchronous request object such that if the arguments indicate a pending asynchronous request and a fulfilled asynchronous request, then the result is a fulfilled asynchronous request object.

Checkout the example application.

License

MIT License

Changelog

Changelog