next-easy-keepalive
Version:
It is an easy-to-use keepAlive library exclusively for nextjs.
196 lines (188 loc) • 7.76 kB
JavaScript
;
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