UNPKG

react-next-keep-alive

Version:
235 lines (229 loc) 9.66 kB
import React, { cloneElement, useRef, useState, memo, useEffect, Fragment } from 'react'; var defaultEnabled = true; var KeepAliveProvider = function KeepAliveProvider(props) { var _componentData$type; var children = props.children, router = props.router; var pageProps = children === null || children === void 0 ? void 0 : children.props; var componentData = cloneElement(children); var CurrentComponent = componentData === null || componentData === void 0 ? void 0 : componentData.type; var keepAliveCache = useRef({}); var _useState = useState(), forceUpdate = _useState[1]; var _ref = (componentData === null || componentData === void 0 ? void 0 : (_componentData$type = componentData.type) === null || _componentData$type === void 0 ? void 0 : _componentData$type.keepAlive) || {}, keepAliveName = _ref.name, keepScrollEnabled = _ref.keepScrollEnabled, applyNewProps = _ref.applyNewProps; var name = typeof keepAliveName === 'function' ? keepAliveName({ props: pageProps, router: router }) : keepAliveName; var isEnabled = function isEnabled() { var _keepAliveCache$curre, _keepAliveCache$curre2; return keepAliveCache === null || keepAliveCache === void 0 ? void 0 : (_keepAliveCache$curre = keepAliveCache.current) === null || _keepAliveCache$curre === void 0 ? void 0 : (_keepAliveCache$curre2 = _keepAliveCache$curre[name]) === null || _keepAliveCache$curre2 === void 0 ? void 0 : _keepAliveCache$curre2.enabled; }; var isKeptAlive = !!name; var keepScroll = !!keepScrollEnabled; if (isKeptAlive && !keepAliveCache.current[name]) { var Component = componentData === null || componentData === void 0 ? void 0 : componentData.type; var MemoComponent = memo(Component); keepAliveCache.current[name] = { Component: MemoComponent, pageProps: pageProps, scrollPos: 0, name: name, enabled: defaultEnabled }; } var handleRouteChangeStart = function handleRouteChangeStart() { var _keepAliveCache$curre3; if (isKeptAlive && keepAliveCache !== null && keepAliveCache !== void 0 && (_keepAliveCache$curre3 = keepAliveCache.current) !== null && _keepAliveCache$curre3 !== void 0 && _keepAliveCache$curre3[name]) { keepAliveCache.current[name].scrollPos = window.scrollY; } }; var handleRouteChangeComplete = function handleRouteChangeComplete() { if (isKeptAlive && isEnabled() && keepScroll) { var _keepAliveCache$curre4; window.scrollTo(0, ((_keepAliveCache$curre4 = keepAliveCache.current[name]) === null || _keepAliveCache$curre4 === void 0 ? void 0 : _keepAliveCache$curre4.scrollPos) || 0); setTimeout(function () { var _keepAliveCache$curre5; window.scrollTo(0, ((_keepAliveCache$curre5 = keepAliveCache.current[name]) === null || _keepAliveCache$curre5 === void 0 ? void 0 : _keepAliveCache$curre5.scrollPos) || 0); }, 0); } }; var handleLoadFromCache = function handleLoadFromCache(event) { var _ref2 = (event === null || event === void 0 ? void 0 : event.detail) || {}, controlsName = _ref2.name, controlsEnabled = _ref2.enabled; if (keepAliveCache.current[controlsName]) { keepAliveCache.current[controlsName].enabled = controlsEnabled; } }; var handleDropCache = function handleDropCache(event) { var _ref3 = (event === null || event === void 0 ? void 0 : event.detail) || {}, dropKeepAliveName = _ref3.name, scrollToTop = _ref3.scrollToTop; if (!dropKeepAliveName) { keepAliveCache.current = {}; } else if (typeof dropKeepAliveName === 'string') { var _keepAliveCache$curre6; (_keepAliveCache$curre6 = keepAliveCache.current) === null || _keepAliveCache$curre6 === void 0 ? true : delete _keepAliveCache$curre6[dropKeepAliveName]; } else if (typeof dropKeepAliveName === 'function') { var _cachesToRemove$filte; var caches = dropKeepAliveName === null || dropKeepAliveName === void 0 ? void 0 : dropKeepAliveName(Object.keys(keepAliveCache.current)); var cachesToRemove = Array.isArray(caches) ? caches : [caches]; cachesToRemove === null || cachesToRemove === void 0 ? void 0 : (_cachesToRemove$filte = cachesToRemove.filter(function (exists) { return exists; })) === null || _cachesToRemove$filte === void 0 ? void 0 : _cachesToRemove$filte.forEach(function (cacheName) { var _keepAliveCache$curre7; return (_keepAliveCache$curre7 = keepAliveCache.current) === null || _keepAliveCache$curre7 === void 0 ? true : delete _keepAliveCache$curre7[cacheName]; }); } if (scrollToTop && typeof window !== 'undefined') { window.scrollTo(0, 0); } forceUpdate({}); }; useEffect(function () { router.events.on('routeChangeStart', handleRouteChangeStart); router.events.on('routeChangeComplete', handleRouteChangeComplete); return function () { router.events.off('routeChangeStart', handleRouteChangeStart); router.events.off('routeChangeComplete', handleRouteChangeComplete); }; }, [router.asPath]); useEffect(function () { if (isKeptAlive) { window.dispatchEvent(new CustomEvent('onKeepAliveMount', { detail: name })); return function () { window.dispatchEvent(new CustomEvent('onKeepAliveUnmount', { detail: name })); }; } }, [CurrentComponent, pageProps]); useEffect(function () { window.addEventListener('keepAliveControls_LoadFromCache', handleLoadFromCache); window.addEventListener('keepAliveControls_DropCache', handleDropCache); return function () { window.removeEventListener('keepAliveControls_LoadFromCache', handleLoadFromCache); window.removeEventListener('keepAliveControls_DropCache', handleDropCache); }; }, []); var getCachedViewProps = function getCachedViewProps(cachedProps) { if (applyNewProps === true) { return pageProps; } if (typeof applyNewProps === 'function') { return applyNewProps(cachedProps, pageProps); } return cachedProps; }; var getKeepAliveEffect = function getKeepAliveEffect(isHidden) { var useKeepAliveEffect = function useKeepAliveEffect(effect, deps) { return useEffect(function () { if (!isHidden) { return effect(); } }, deps); }; return useKeepAliveEffect; }; return React.createElement(Fragment, null, (!isKeptAlive || !isEnabled()) && children, React.createElement("div", { style: { display: isKeptAlive && isEnabled() ? 'block' : 'none' }, id: "keep-alive-container", "data-keepalivecontainer": true }, Object.entries(keepAliveCache.current).map(function (_ref4) { var cacheName = _ref4[0], _ref4$ = _ref4[1], Component = _ref4$.Component, cachedProps = _ref4$.pageProps; return React.createElement("div", { key: cacheName, style: { display: name === cacheName ? 'block' : 'none' }, "data-keepalive": cacheName, "data-keepalive-hidden": name !== cacheName }, React.createElement(Component, Object.assign({ isHiddenByKeepAlive: name !== cacheName, useEffect: getKeepAliveEffect(name !== cacheName) }, getCachedViewProps(cachedProps)))); }))); }; var defaultOpts = { keepScrollEnabled: true, applyNewProps: false }; var withKeepAlive = function withKeepAlive(Component, name, opts) { if (opts === void 0) { opts = defaultOpts; } var KeepAlive = function KeepAlive(props) { return React.createElement(Fragment, null, React.createElement(Component, Object.assign({}, props))); }; if (Component.getInitialProps) { KeepAlive.getInitialProps = Component.getInitialProps; } var _ref = opts || {}, keepScrollEnabled = _ref.keepScrollEnabled, applyNewProps = _ref.applyNewProps; KeepAlive.keepAlive = { name: name, keepScrollEnabled: keepScrollEnabled, applyNewProps: applyNewProps }; return KeepAlive; }; var useKeepAliveMountEffect = function useKeepAliveMountEffect(name, effect) { var handleMountedEvent = function handleMountedEvent(e) { if ((e === null || e === void 0 ? void 0 : e.detail) === name && typeof effect === 'function') { effect(); } }; useEffect(function () { window.addEventListener('onKeepAliveMount', handleMountedEvent); return function () { window.removeEventListener('onKeepAliveMount', handleMountedEvent); }; }, []); }; var useKeepAliveUnmountEffect = function useKeepAliveUnmountEffect(name, effect) { var handleUnmountedEvent = function handleUnmountedEvent(e) { if ((e === null || e === void 0 ? void 0 : e.detail) === name && typeof effect === 'function') { effect(); } }; useEffect(function () { window.addEventListener('onKeepAliveUnmount', handleUnmountedEvent); return function () { window.removeEventListener('onKeepAliveUnmount', handleUnmountedEvent); }; }, []); }; function keepAliveLoadFromCache(name, enabled) { if (typeof window !== 'undefined') { window.dispatchEvent(new CustomEvent('keepAliveControls_LoadFromCache', { detail: { name: name, enabled: enabled } })); } } function keepAliveDropCache(name, scrollToTop) { if (typeof window !== 'undefined') { window.dispatchEvent(new CustomEvent('keepAliveControls_DropCache', { detail: { name: name, scrollToTop: scrollToTop } })); } } export { KeepAliveProvider, keepAliveDropCache, keepAliveLoadFromCache, useKeepAliveMountEffect, useKeepAliveUnmountEffect, withKeepAlive }; //# sourceMappingURL=index.modern.js.map