@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
JavaScript
;
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;