UNPKG

@vgbire/react-keep-alive

Version:
91 lines (90 loc) 3.54 kB
import React, { useContext, useState, createContext, useEffect } from 'react'; import { useLocation, useMatches } from 'react-router'; import { RouterTabs } from './router-tabs'; import { RouterCache } from './router-cache'; const RouterKeepAliveContext = createContext({ activateds: {}, deactivateds: {} }); RouterKeepAliveContext.displayName = 'RouterKeepAlive'; export const RouterKeepAlive = ({ mode = 'path', nameKey = 'name', cacheMaxRemove, theme = 'light', size = 'middle', max = 10, custom, bodyStyles, children, }) => { const { pathname, search } = useLocation(); const matches = useMatches(); const currentHandle = matches[matches.length - 1].handle; const [activateds, setActivateds] = useState({}); const [deactivateds, setDeactivateds] = useState({}); const [active, setActive] = useState(''); const [tabs, setTabs] = useState([]); const [caches, setCaches] = useState([]); const dispatchActivateds = () => { var _a; const key = mode === 'path' ? pathname : pathname + search; // 调用activateds if ((_a = activateds[key]) === null || _a === void 0 ? void 0 : _a.length) { activateds[key].forEach((item) => { const deactivated = item(); if (deactivated) { if (!deactivateds[key]) { deactivateds[key] = []; } deactivateds[key].push(deactivated); setDeactivateds(Object.assign({}, deactivateds)); } }); } }; useEffect(() => { const key = mode === 'path' ? pathname : pathname + search; // 调用deactivateds方法 setActive((active) => { var _a; if ((_a = deactivateds[active]) === null || _a === void 0 ? void 0 : _a.length) { deactivateds[active].forEach((item) => { item(); }); delete deactivateds[active]; setDeactivateds(Object.assign({}, deactivateds)); } return key; }); dispatchActivateds(); const label = currentHandle === null || currentHandle === void 0 ? void 0 : currentHandle[nameKey]; const existTab = tabs.find((item) => item.key === key); if (!existTab && label) { setTabs([ ...tabs, { key: key, label, }, ]); } if (existTab && existTab.label !== label) { existTab.label = label; setTabs([...tabs]); } }, [pathname, search, mode]); return (React.createElement(RouterKeepAliveContext.Provider, { value: { activateds, setActivateds, deactivateds, setDeactivateds, active, setActive, tabs, setTabs, caches, setCaches, nameKey, cacheMaxRemove, theme, size, max, } }, custom ? (children) : (React.createElement(React.Fragment, null, React.createElement(RouterTabs, null), React.createElement(RouterCache, { styles: bodyStyles }, children))))); }; export const useKeepAliveContext = () => { const context = useContext(RouterKeepAliveContext); if (!context) { throw new Error('useKeepAliveContext 必须在 RouterKeepAliveContext 中使用'); } return context; };