UNPKG

@alextewpin/use-promise

Version:

Hook for declarative promises. Useful for fetching data, sending forms and doing other async stuff right in component. Tiny, easy to use, TypeScript definitions included. Inspired by outstanding [react-async](https://www.npmjs.com/package/react-async) lib

114 lines (99 loc) 2.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _react = require("react"); var actionTypes; (function (actionTypes) { actionTypes["run"] = "run"; actionTypes["resolve"] = "resolve"; actionTypes["reject"] = "reject"; actionTypes["cancel"] = "cancel"; })(actionTypes || (actionTypes = {})); var defaultState = { data: undefined, error: undefined, payload: undefined, isPending: false }; var reducer = function reducer(state, action) { switch (action.type) { case actionTypes.run: return Object.assign({}, state, { error: undefined, payload: action.payload, isPending: true }); case actionTypes.resolve: return Object.assign({}, state, { data: action.payload, error: undefined, isPending: false }); case actionTypes.reject: return Object.assign({}, state, { error: action.payload, isPending: false }); case actionTypes.cancel: return Object.assign({}, state, { isPending: false }); default: return state; } }; var usePromise = function usePromise(_ref) { var promiseThunk = _ref.promiseThunk, onResolve = _ref.onResolve, onReject = _ref.onReject; var pendingPromiseRef = (0, _react.useRef)(null); var usedReducer = (0, _react.useReducer)(reducer, defaultState); var state = usedReducer[0]; var dispatch = usedReducer[1]; (0, _react.useEffect)(function () { return function () { pendingPromiseRef.current = null; dispatch({ type: actionTypes.cancel }); }; }, [dispatch]); var run = (0, _react.useCallback)(function () { for (var _len = arguments.length, payload = new Array(_len), _key = 0; _key < _len; _key++) { payload[_key] = arguments[_key]; } dispatch({ type: actionTypes.run, payload: payload }); var pendingPromise = promiseThunk.apply(void 0, payload).then(function (data) { if (pendingPromise === pendingPromiseRef.current) { dispatch({ payload: data, type: actionTypes.resolve }); if (onResolve) { onResolve.apply(void 0, [data].concat(payload)); } } })["catch"](function (error) { if (pendingPromise === pendingPromiseRef.current) { dispatch({ payload: error, type: actionTypes.reject }); if (onReject) { onReject.apply(void 0, [error].concat(payload)); } } }); pendingPromiseRef.current = pendingPromise; }, [dispatch, promiseThunk, onReject, onResolve]); return Object.assign({}, state, { run: run }); }; var _default = usePromise; exports["default"] = _default;