tdreyno/pretty-please

View on GitHub
src/react/useRemoteData.ts

Summary

Maintainability
A
0 mins
Test Coverage
import { useCallback, useState } from "react"
import {
  fold,
  initialize,
  pending,
  RemoteData,
  succeed,
} from "../RemoteData/RemoteData"
import { Task } from "../Task/Task"

export const useRemoteData = <E, S>(
  task: () => Task<E, S>,
): [
  state: RemoteData<E, S>,
  caseof: <R>(
    onInitialized: () => R,
    onPending: () => R,
    onFailure: (error: E) => R,
    onSuccess: (result: S) => R,
  ) => R,
  request: () => void,
] => {
  const [state, setState] = useState<RemoteData<E, S>>(initialize<E, S>())

  const request = useCallback(() => {
    if (state.type !== "Initialized") {
      return
    }

    setState(pending<E, S>())

    task().mapBoth(fail, succeed).fork(setState, setState)
  }, [state, setState])

  const caseof = useCallback(
    <R>(
      onInitialized: () => R,
      onPending: () => R,
      onFailure: (error: E) => R,
      onSuccess: (result: S) => R,
    ): R => {
      return fold<E, S, R>(
        onInitialized,
        onPending,
        onFailure,
        onSuccess,
        state,
      )
    },
    [state],
  )

  return [state, caseof, request]
}