use-axios
Version:
Simple Axios hook for React. Use React Suspense to show loading indicator and Error Boundary to show request errors.
198 lines (165 loc) • 5.31 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import { useEffect, useReducer } from 'react';
import axios from 'axios';
import stringify from 'fast-json-stable-stringify';
import get from '@postinumero/map-get-with-default';
import obsoleteWithReplacement from './utils/obsoleteWithReplacement';
export var create = function create(config) {
var axiosInstance = typeof config === 'function' ? config : axios.create(config);
var responses = new Map();
var requests = new Map();
var updaters = new Map();
function request() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var key = stringify(args);
var suspender = new Promise(
/*#__PURE__*/
function () {
var _ref = _asyncToGenerator(
/*#__PURE__*/
_regeneratorRuntime.mark(function _callee(resolve) {
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.prev = 0;
_context.t0 = responses;
_context.t1 = key;
_context.next = 5;
return axiosInstance.apply(void 0, args);
case 5:
_context.t2 = _context.sent;
_context.t3 = [null, _context.t2];
_context.t0.set.call(_context.t0, _context.t1, _context.t3);
_context.next = 13;
break;
case 10:
_context.prev = 10;
_context.t4 = _context["catch"](0);
responses.set(key, [_context.t4]);
case 13:
resolve();
case 14:
case "end":
return _context.stop();
}
}
}, _callee, null, [[0, 10]]);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}());
requests.set(key, suspender);
return suspender;
}
var getUpdaters = function getUpdaters(key) {
return get.call(updaters, key, function () {
return new Set();
});
};
function useAxios() {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
var key = stringify(args);
var _useReducer = useReducer(function (x) {
return x + 1;
}, 0),
_useReducer2 = _slicedToArray(_useReducer, 2),
forceUpdate = _useReducer2[1];
useEffect(function () {
var updaters = getUpdaters(key);
updaters.add(forceUpdate);
return function () {
updaters.delete(forceUpdate);
if (!updaters.size) {
requests.delete(key);
responses.delete(key);
}
};
}, [key]);
if (responses.has(key)) {
var _responses$get = responses.get(key),
_responses$get2 = _slicedToArray(_responses$get, 2),
error = _responses$get2[0],
data = _responses$get2[1];
if (error) {
throw error;
}
return data;
}
if (!requests.has(key)) {
request.apply(void 0, args);
}
throw requests.get(key);
}
function refetch() {
return _refetch.apply(this, arguments);
}
function _refetch() {
_refetch = _asyncToGenerator(
/*#__PURE__*/
_regeneratorRuntime.mark(function _callee2() {
var _len3,
args,
_key3,
key,
updaters,
_args2 = arguments;
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
for (_len3 = _args2.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = _args2[_key3];
}
key = stringify(args);
updaters = getUpdaters(key);
if (!updaters.size) {
_context2.next = 7;
break;
}
_context2.next = 6;
return request.apply(void 0, args);
case 6:
updaters.forEach(function (updater) {
return updater();
});
case 7:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return _refetch.apply(this, arguments);
}
function useAxiosSafe() {
try {
return [null, useAxios.apply(void 0, arguments)];
} catch (error) {
// If error is a promise, rethrow it for React Suspense
if (Promise.resolve(error) === error) {
throw error;
}
return [error, {}];
}
}
return {
useAxios: useAxios,
refetch: refetch,
useAxiosSafe: useAxiosSafe
};
};
var _create = create(axios),
useAxios = _create.useAxios,
refetch = _create.refetch,
useAxiosSafe = _create.useAxiosSafe;
export { useAxios as default, refetch, useAxiosSafe };
export var reload = obsoleteWithReplacement(refetch, 'reload');
//# sourceMappingURL=index.js.map