Skip to content
This repository has been archived by the owner on Feb 17, 2023. It is now read-only.

vladagurets/react-cancelable

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Stand With Ukraine

react-cancelable

Internet traffic economizer


version downloads


Table of Contents

  1. Motivation
  2. Instalation
  3. Tools
    1. useCancelableReq
    2. useCancelableImg
    3. cancelable HOF
  4. Fetch vs Axios
  5. Best practices (WIP)

Motivation

In most of cases client consumes a lot of excess internet traffic. Modern web applications make a huge bunch of requests per conventional time unit then a lot of clients don't wait until all requests made by web app are finished. As a result, the browser expects data that will no longer be used.

With react-cancelable you can easily cancel requests at any step of the request's lifecycle and consume fewer traffic bytes.


Instalation

npm install react-cancelable
yarn add react-cancelable

Before installation be sure you have installed the required peer dependencies to your project


{
  "react": "^17.0.0",
}

Tools


useCancelableReq


Make cancelable request. Hook helps you to control request canceling by React Component Lifecycle or by your own.


Signature


type RequestFn = (controller: AbortController) => Promise<any>

type Opts = {
  isLazy?: boolean;
  cancelOnUnmount?: boolean;
  controller?: AbortController;
  onComplete?: (res: any) => void;
  onFail?: (error: any) => void
  onCancel?: VoidFunction;
}

type Artefacts = {
  res?: Response;
  data?: any;
  error?: any;
  isLoading: boolean;
  cancel: VoidFunction,
  makeLazyRequest: VoidFunction | null;
}

useCancelableReq(fn: RequestFn, opts?: Opts): Artefacts

API


Name Description Default
isLazy Control request by your own if true. By default, a request will be made on the component mount false
cancelOnUnmount Request will be canceled on component unmount if true true
controller By default component will create instance automaticaly under the hood. If yoo want to controll multiple requests with one conteroller pass your own instance of AbortControler undefined
onComplete Trigger after request is completed undefined
onFail Trigger after request is failed undefined
onCancel Trigger after request is canceled undefined
res Response object undefined
data Payload of a request undefined
error Error of a request undefined
isLoading Flag to determine active status of request. If isLazy is true isLoading is false by default true
cancel Request cancel trigger function
makeLazyRequest Make request trigger. If isLazy is true makeLazyRequest is function null

Example


import React from 'react'
import { useCancelableReq } from 'react-cancelable'

function makeRequest(controller) {
  // Pass signal to your request
  return fetch("YOUR_ENDPOINT", { signal: controller.signal })
}

function Item() {
  const { data, isLoading, error } = useCancelableReq(makeRequest)

  return (
    <>
      {isLoading && <span>Loading...</span>}
      {error && <span>Error occured</span>}
      {data && <span>Data is fetched</span>}
    </>
  )
}

useCancelableImg


Make cancelable request. Hook helps you to cancel requested image.


Signature


type RequestFn = (controller: AbortController) => Promise<any>

type Opts = {
  isLazy?: boolean;
  cancelOnUnmount?: boolean;
  controller?: AbortController;
  onComplete?: (res: any) => void;
  onFail?: (error: any) => void
  onCancel?: VoidFunction;
}

type Artefacts = {
  res?: Response;
  src?: string;
  error?: any;
  isLoading: boolean;
  cancel: VoidFunction,
  makeLazyRequest: VoidFunction | null;
}

useCancelableImg(fn: RequestFn, opts?: Opts): Artefacts

API


Name Description Default
isLazy Control request by your own if true. By default, a request will be made on the component mount false
cancelOnUnmount Request will be canceled on component unmount if true true
controller By default component will create instance automaticaly under the hood. If yoo want to controll multiple requests with one conteroller pass your own instance of AbortControler undefined
onComplete Trigger after request is completed undefined
onFail Trigger after request is failed undefined
onCancel Trigger after request is canceled undefined
res Response object undefined
src Generated ObjectURI to Blob image after request done undefined
error Error of a request undefined
isLoading Flag to determine active status of request. If isLazy is true isLoading is false by default true
cancel Request cancel trigger function
makeLazyRequest Make request trigger. If isLazy is true makeLazyRequest is function null

Example


import React from 'react'
import { useCancelableReq } from 'react-cancelable'


function getImage(controller) {
  // Pass signal to your request
  return fetch('IMAGE_URL', { signal: controller.signal })
}

function Item() {
  const { src, isLoading, error } = useCancelableImg(getImage)

  return (
    <>
      {isLoading && <span>Loading...</span>}
      {src && <img src={src} />}
    </>
  )
}

cancelable HOF


Hight order function to create cancelable requests


Signature


type RequestFn = (controller: AbortController) => Promise<any>

type RequestPromise = Promise<any> & { cancel: VoidFunction }

cancelable(fn: RequestFn, controller?: AbortController): RequestPromise

API


Name Description Default
fn Callback that returns Promise generated by HTTP client function
controller By default component will create instance automaticaly under the hood. If yoo want to controll multiple requests with one conteroller pass your own instance of AbortControler undefined
cancel Request cancel trigger. Property added to returned Promise function

Example


import { cancelable } from 'react-cancelable'

function makeRequest(controller) {
  return fetch("YOUR_ENDPOINT", { signal: controller.signal })
}

// Wrap your request
const request = cancelable(makeRequest)

setTimeout(() => {
  // Cancel request later
  request.cancel()
}, 1000)

Fetch vs Axios

There is no difference what HTTP client you use. Package have one important rule - HTTP client must accept AbortController signal.

function makeFetchRequest(controller) {
  return fetch("YOUR_ENDPOINT", { signal: controller.signal })
}

function makeAxiosRequest(controller) {
  return axios.get("YOUR_ENDPOINT", { signal: controller.signal })
}

Best practices (WIP)

Cancel multiple similar request via one AbortController. Each helper can take controller parameter.

import { cancelable } from 'react-cancelable'

const controller = new AbortController()

function makeRequest(controller) {
  return fetch("YOUR_ENDPOINT", { signal: controller.signal })
}

// Make requests
new Array(100).fill(0).forEach(() => { cancelable(makeRequest, controller) } )

setTimeout(() => {
  // Stop all pending requests
  controller.abort()
}, 1000)