UNPKG

next-easy-keepalive

Version:

It is an easy-to-use keepAlive library exclusively for nextjs.

196 lines (188 loc) 7.76 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var _debounce = _interopDefault(require('lodash/debounce')); function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } var initialValue = { current: { backHistory: {}, isBack: false }, alwaysRemember: false, maxPage: 10 }; var BackControlContext = /*#__PURE__*/React.createContext(initialValue); var KeepAliveProvider = function KeepAliveProvider(_ref) { var children = _ref.children, router = _ref.router, _ref$alwaysRemember = _ref.alwaysRemember, alwaysRemember = _ref$alwaysRemember === void 0 ? false : _ref$alwaysRemember, _ref$maxPage = _ref.maxPage, maxPage = _ref$maxPage === void 0 ? 10 : _ref$maxPage; // const pathname = usePathname(); var backHistoryStore = React.useRef(initialValue.current); var scrollPos = React.useRef(0); React.useEffect(function () { var pathName = window.location.pathname; var saveScroll = _debounce(function () { scrollPos.current = window.scrollY || window.pageYOffset; }, 100); var backEventCatch = function backEventCatch() { backHistoryStore.current.isBack = true; setTimeout(function () { backHistoryStore.current.isBack = false; }, 500); }; window.removeEventListener('popstate', backEventCatch); window.addEventListener('popstate', backEventCatch); window.removeEventListener('scroll', saveScroll); window.addEventListener('scroll', saveScroll); return function () { window.removeEventListener('scroll', saveScroll); window.removeEventListener('popstate', backEventCatch); if (backHistoryStore.current.backHistory[pathName]) { backHistoryStore.current.backHistory[pathName].scrollPos = scrollPos.current; } }; }, [router]); return ( // eslint-disable-next-line react/jsx-no-constructed-context-values React__default.createElement(BackControlContext.Provider, { value: _extends({}, backHistoryStore, { alwaysRemember: alwaysRemember, maxPage: maxPage > 17 ? 15 : maxPage }) }, children) ); }; var useKeepAlive = function useKeepAlive(key, option) { var _ref = option || {}, _ref$alwaysRemember = _ref.alwaysRemember, optionAlwaysRemember = _ref$alwaysRemember === void 0 ? true : _ref$alwaysRemember, _ref$store = _ref.store, store = _ref$store === void 0 ? true : _ref$store; var _useContext = React.useContext(BackControlContext), backContext = _useContext.current, allAlwaysRemember = _useContext.alwaysRemember, maxPage = _useContext.maxPage; var alwaysRemember = allAlwaysRemember && optionAlwaysRemember; var pathName = typeof window !== 'undefined' && window.location.pathname ? window.location.pathname : 'temp'; // Make it visible to the window object for easy debugging in debug tools if (typeof window !== 'undefined') window.__BACK_HISTORY__ = backContext.backHistory; var tempStore = React.useRef({ state: {}, ref: {} }); var getCacheData = function getCacheData() { var _backContext$backHist; var pageCacheData = (_backContext$backHist = backContext.backHistory[pathName]) == null ? void 0 : _backContext$backHist.data; return (backContext.isBack || alwaysRemember) && pageCacheData ? pageCacheData[key] : undefined; }; // useEffect hook that runs only when not going back var useNotBackEffect = function useNotBackEffect(func, deps) { if (deps === void 0) { deps = []; } return React.useEffect(function () { var _backContext$backHist2; var pageCacheData = ((_backContext$backHist2 = backContext.backHistory[pathName]) == null ? void 0 : _backContext$backHist2.data) || {}; if (!backContext.isBack || !pageCacheData[key]) { func(); } }, [].concat(deps)); }; // useEffect hook that runs only when going back var useBackActive = function useBackActive(func, deps) { if (deps === void 0) { deps = []; } return React.useEffect(function () { var _backContext$backHist3; var pageCacheData = ((_backContext$backHist3 = backContext.backHistory[pathName]) == null ? void 0 : _backContext$backHist3.data) || {}; if (backContext.isBack && pageCacheData[key]) { func(); } }, [].concat(deps)); }; var useMemState = function useMemState(state, keyName) { var cacheData = getCacheData(); var cacheState = cacheData && cacheData.state[keyName]; var resultState = React.useState(cacheState != null ? cacheState : state); tempStore.current.state[keyName] = resultState[0]; return resultState; }; var useMemRef = function useMemRef(ref, keyName) { var cacheData = getCacheData(); var cacheRef = cacheData && cacheData.ref[keyName].current; var resultRef = React.useRef(cacheRef != null ? cacheRef : ref); tempStore.current.ref[keyName] = resultRef; return resultRef; }; React.useLayoutEffect(function () { if (backContext.isBack || alwaysRemember) { if (backContext.backHistory[pathName]) { var backHistory = backContext.backHistory[pathName]; if (backHistory.scrollPos > 0) window.scrollTo(0, backHistory.scrollPos); } } }, []); React.useEffect(function () { return function () { if (store) { var _backContext$backHist4, _backContext$backHist5, _backContext$backHist6, _extends2, _extends3; var _tempStore$current = tempStore.current, state = _tempStore$current.state, ref = _tempStore$current.ref; var prevData = ((_backContext$backHist4 = backContext.backHistory[pathName]) == null ? void 0 : _backContext$backHist4.data) || {}; var history = _extends({}, backContext.backHistory, (_extends3 = {}, _extends3[pathName] = { order: Object.keys(backContext.backHistory).length, scrollPos: (_backContext$backHist5 = (_backContext$backHist6 = backContext.backHistory[pathName]) == null ? void 0 : _backContext$backHist6.scrollPos) != null ? _backContext$backHist5 : 0, data: _extends({}, prevData, (_extends2 = {}, _extends2[key] = { state: state, ref: ref }, _extends2)) }, _extends3)); if (Object.entries(history).length > maxPage) { history = Object.entries(history).sort(function (_ref2, _ref3) { var a = _ref2[1]; var b = _ref3[1]; return ((b == null ? void 0 : b.order) || 0) - ((a == null ? void 0 : a.order) || 0); }).filter(function (_, idx) { return idx !== 0; }).reduce(function (acc, _ref4) { var _extends4; var key = _ref4[0], value = _ref4[1]; return _extends({}, acc, (_extends4 = {}, _extends4[key] = value, _extends4)); }, {}); } backContext.backHistory = history; } }; }, []); return { isBack: backContext.isBack, useNotBackEffect: useNotBackEffect, useBackActive: useBackActive, useMemState: useMemState, useMemRef: useMemRef }; }; exports.KeepAliveProvider = KeepAliveProvider; exports.useKeepAlive = useKeepAlive; //# sourceMappingURL=next-easy-keepalive.cjs.development.js.map