Coder Social home page Coder Social logo

use-axios's Introduction

use-axios

Source code and demo for a generic Axios call React Hook. Live example

Want to suggest an improvement? I'm all ears! Please file an issue or open a PR!

Usage

import React, { useState } from "react";
import { useAxios } from "./use-axios";

const App = () => {
  const [id, setId] = useState("1");
  const axiosConfig = { method: "get", timeout: 2500 };
  const { isLoading, isError, response } = useAxios(
    `https://pokeapi.co/api/v2/pokemon/${id}`,
    axiosConfig
  );

  return (
    {response?.data && <div>{data}</div>}
    {isLoading && <LoadingIcon/>}
    {isError && <ErrorMsg/>}
  );
};

Overview

useAxios is an Axios-specific implementation of my generic useAsyncFunc React hook.

One issue for async operations is when the return value is no longer required. For example, the user leaves the page (the requesting component is unmounted) or the user provides a new search query (the old search query's response is superfluous).

You might see an error like this:

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

In these situations, we want to cancel the initial request. The browser Web API provides the AbortController interface; it is a controller object that allows you to abort one or more Web requests. Axios provides similar capability with the CancelToken class. CancelTokens are straightforward to implement if you are already using the Axios library. You read a little more about each implementation here.

useAxios

/**
 *
 * @param {string} url      - The url to call
 * @param {object} [config] - The axios config object; defaults to GET, etc
 * @returns {state}         - { isLoading, isError, response }
 */
const useAxios = (url, config) => {
  // useReducer manages the local complex state of the async func hook's lifecycle.
  // See the source code for the full reducer!
  // NOTE: it is easy to modify or expand the reducer to fit your needs.
  const [state, dispatch] = useReducer(axiosReducer, {
    isLoading: false,
    isError: false
  });

  useEffect(() => {
    // Declare Axios cancel token
    const source = CancelToken.source();

    // Define the axios call
    const callAxios = async () => {
      // Begin with a clean state
      dispatch({ type: "AXIOS_INIT" });

      try {
        // Straightforward axios call,
        // With cancel token inserted into config
        const response = await axios(url, {
          ...config,
          cancelToken: source.token
        });
        dispatch({ type: "AXIOS_SUCCESS", payload: response });
      } catch (err) {
        // Two options on error:
        // 1. If component is mounted but error is an axios cancel, simply return and move on
        // 2. For all other errors, assume async failure and dispatch failure action
        if (isCancel(err)) {
          console.log("Canceled request.");
          return;
        }
        dispatch({ type: "AXIOS_FAILURE" });
      }
    };

    // Invoke the defined axios call
    callAxios();

    // On unmount, cancel the request
    return () => {
      source.cancel("Operation canceled.");
    };

    // NOTE: here be dragon!
    // My instinct was include the axios config in this array, e.g. [url, config]
    // This causes an infinite re-render loop that I have not debugged yet :-/
  }, [url]);

  return state;
};

export default useAxios;

Conclusion

It is good to cancel superfluous requests so that they do not become memory leaks! I hope you find this example helpful.

use-axios's People

Contributors

kwhitejr avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

lucasmontegu

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.