@vgbire/react-keep-alive
Version:
React keepAlive
91 lines (90 loc) • 3.54 kB
JavaScript
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;
};