ahooks
Version:
react hooks library
75 lines (74 loc) • 2.66 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _dayjs = _interopRequireDefault(require("dayjs"));
var _react = require("react");
var _useLatest = _interopRequireDefault(require("../useLatest"));
var _utils = require("../utils");
var calcLeft = function calcLeft(target) {
if (!target) {
return 0;
}
// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
var left = (0, _dayjs["default"])(target).valueOf() - Date.now();
return left < 0 ? 0 : left;
};
var parseMs = function parseMs(milliseconds) {
return {
days: Math.floor(milliseconds / 86400000),
hours: Math.floor(milliseconds / 3600000) % 24,
minutes: Math.floor(milliseconds / 60000) % 60,
seconds: Math.floor(milliseconds / 1000) % 60,
milliseconds: Math.floor(milliseconds) % 1000
};
};
var useCountdown = function useCountdown() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _ref = options || {},
leftTime = _ref.leftTime,
targetDate = _ref.targetDate,
_ref$interval = _ref.interval,
interval = _ref$interval === void 0 ? 1000 : _ref$interval,
onEnd = _ref.onEnd;
var memoLeftTime = (0, _react.useMemo)(function () {
return (0, _utils.isNumber)(leftTime) && leftTime > 0 ? Date.now() + leftTime : undefined;
}, [leftTime]);
var target = 'leftTime' in options ? memoLeftTime : targetDate;
var _useState = (0, _react.useState)(function () {
return calcLeft(target);
}),
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
timeLeft = _useState2[0],
setTimeLeft = _useState2[1];
var onEndRef = (0, _useLatest["default"])(onEnd);
(0, _react.useEffect)(function () {
if (!target) {
// for stop
setTimeLeft(0);
return;
}
// 立即执行一次
setTimeLeft(calcLeft(target));
var timer = setInterval(function () {
var _a;
var targetLeft = calcLeft(target);
setTimeLeft(targetLeft);
if (targetLeft === 0) {
clearInterval(timer);
(_a = onEndRef.current) === null || _a === void 0 ? void 0 : _a.call(onEndRef);
}
}, interval);
return function () {
return clearInterval(timer);
};
}, [target, interval]);
var formattedRes = (0, _react.useMemo)(function () {
return parseMs(timeLeft);
}, [timeLeft]);
return [timeLeft, formattedRes];
};
var _default = exports["default"] = useCountdown;