UNPKG

use-invariant

Version:

- <a target="_blank" rel="noopener noreferrer" href='https://codesandbox.io/s/usefetch-in-nextjs-nn9fm'>Example - Next.js</a> - <a target="_blank" rel="noopener noreferrer" href='https://codesandbox.io/embed/km04k9k9x5'>Examples - create-react-app</a>

131 lines 6.15 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = require("react"); const FetchContext_1 = __importDefault(require("./FetchContext")); const types_1 = require("./types"); const utils_1 = require("./utils"); function useFetch(arg1, arg2) { const context = react_1.useContext(FetchContext_1.default); utils_1.invariant(!!arg1 && !!context.url, 'The first argument of useFetch is required unless you have a global url setup like: <Provider url="https://example.com"></Provider>'); let url = context.url || null; let options = {}; let onMount = false; let baseUrl = ''; let method = types_1.HTTPMethod.GET; const handleOptions = react_1.useCallback((opts) => { if (true) { // take out all the things that are not normal `fetch` options // need to take this out of scope so can set the variables below correctly let { url, onMount, timeout, baseUrl } = opts, rest = __rest(opts, ["url", "onMount", "timeout", "baseUrl"]); options = Object.assign({ signal: undefined }, rest); } if (context.url) url = context.url; if (opts.url) url = opts.url || context.url || ''; if (opts.onMount) onMount = opts.onMount; if (opts.method) method = opts.method; if (opts.baseUrl) baseUrl = opts.baseUrl; }, []); if (typeof arg1 === 'string') { // if we have a default url from context, and // arg1 is a string, and we're not using graphql // we treat arg1 as a relative route url = context.url && !context.graphql ? context.url + arg1 : arg1; if (arg2 && utils_1.isObject(arg2)) handleOptions(arg2); } else if (utils_1.isObject(arg1)) { handleOptions(arg1 || {}); } const [data, setData] = react_1.useState(); const [loading, setLoading] = react_1.useState(onMount); const [error, setError] = react_1.useState(); const controller = react_1.useRef(); const fetchData = react_1.useCallback((method) => (fetchArg1, fetchArg2) => __awaiter(this, void 0, void 0, function* () { if ('AbortController' in window) { controller.current = new AbortController(); options.signal = controller.current.signal; } let query = ''; // post | patch | put | etc. if (utils_1.isObject(fetchArg1) && method.toLowerCase() !== 'get') { options.body = JSON.stringify(fetchArg1); // relative routes } else if (baseUrl && typeof fetchArg1 === 'string') { url = baseUrl + fetchArg1; if (utils_1.isObject(fetchArg2)) options.body = JSON.stringify(fetchArg2); } if (typeof fetchArg1 === 'string' && typeof fetchArg2 === 'string') query = fetchArg2; try { setLoading(true); const response = yield fetch(url + query, Object.assign({ method }, context.options, options, { headers: Object.assign({ // default content types http://bit.ly/2N2ovOZ Accept: 'application/json', 'Content-Type': 'application/json' }, (context.options || {}).headers, options.headers) })); let data = null; try { data = yield response.json(); } catch (err) { data = yield response.text(); } setData(data); } catch (err) { if (err.name !== 'AbortError') setError(err); } finally { controller.current = null; setLoading(false); } }), [url]); const get = react_1.useCallback(fetchData(types_1.HTTPMethod.GET), []); const post = react_1.useCallback(fetchData(types_1.HTTPMethod.POST), []); const patch = react_1.useCallback(fetchData(types_1.HTTPMethod.PATCH), []); const put = react_1.useCallback(fetchData(types_1.HTTPMethod.PUT), []); const del = react_1.useCallback(fetchData(types_1.HTTPMethod.DELETE), []); const query = react_1.useCallback((query, variables) => post({ query, variables }), []); const mutate = react_1.useCallback((mutation, variables) => post({ mutation, variables }), []); const abort = react_1.useCallback(() => { controller.current && controller.current.abort(); }, []); const request = react_1.useMemo(() => ({ get, post, patch, put, del, delete: del, abort, query, mutate }), []); react_1.useEffect(() => { const methodName = method.toLowerCase(); if (onMount) request[methodName](); }, []); return Object.assign([data, loading, error, request], Object.assign({ data, loading, error, request }, request)); } exports.useFetch = useFetch; exports.default = useFetch; //# sourceMappingURL=useFetch.js.map