use-async-reducer

Provides a reducer to simplify handling of async actions

Usage no npm install needed!

<script type="module">
  import useAsyncReducer from 'https://cdn.skypack.dev/use-async-reducer';
</script>

README

use-async-reducer

An unoppininated hook to help manage async actions in React

npm codecov Build Status NPM

This package provides only a reducer to manage state, see use-async-call for an abstraction which manages hook lifecycle and boilerplate reduction

Install

npm install use-async-reducer

Useage

Basic Example

import {useEffect} from 'react'
import useAsyncReducer from 'use-async-reducer'

function DataLoadingComponent({id}) {
  const [response, actions] = useAsyncReducer()

  useEffect(() => {
    const fetchData = async () => {
      actions.initialize()
      try {
        actions.success(await Api.fetchUser(id))
      } catch (error) {
        action.failure(error)
      }
    }
  }, [id])

  return (
    <>
      {response.loading && <div>Loading...</div>}
      {response.data && <div>{response.data.user.name}</div>}
      {response.error && <div>{response.error.message}</div>}
    </>
  )
}

Example with updating data

import {useEffect, useCallback} from 'react'
import useAsyncReducer, {Loadable} from 'use-async-reducer'

const LoadingIndicator: React.FC<Loadable<any>> = ({loading, data, error}) => {
  if (error) {
    return `Error: ${error.message}`
  }

  if (loading && data === null) {
    return 'Loading initial data...'
  }

  if (loading) {
    return 'Updating data...'
  }

  return null
}

function DataLoadingComponent({id}) {
  const [response, actions] = useAsyncReducer()

  useEffect(() => {
    const fetchData = async () => {
      actions.initialize()
      try {
        actions.success(await Api.fetchUser(id))
      } catch (error) {
        action.failure(error)
      }
    }
  }, [id])

  const updateData = useCallback(async () => {
    actions.request()
    try {
      actions.success(await Api.fetchUser(id))
    } catch (error) {
      action.failure(error)
    }
  }, [])

  return (
    <>
      <LoadingIndicator {...response} />
      {response.data && (
        <>
          <pre>{JSON.stringify(data, null, 2)}</pre>
          <button onClick={updateData}>Refresh Data</button>
        </>
      )}
    </>
  )
}