Utilities for rendering JSX with respect to one or more asynchronous operations.
npm install --save @mfbtech/react-async-rendererAt 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 withcreateAsyncRenderer.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.