前言
在 vue 中可以使用 keep-alive 组件去缓存组件,切换到其他页面不会销毁被缓存的组件
而在 react 中则没有这种设计
思路
在 react 中提供了createPortalApi
我们可以吧组件放在自定义的一个容器中,当需要展示的时候拿出来展示
定义一个容器用来将 children 存储到该容器,该容器会在 active 为 true 的时候将组件添加到containerRef 中
当为 false 会将其在 DOM 结构中 remove
代码
import React, { useRef, useLayoutEffect } from "react"
import ReactDOM from 'react-dom';
type IProps = {
active: boolean;
children: React.ReactNode;
}
const Conditional: React.FC<IProps> = props => {
const {current: targetElement} = useRef(document.createElement('div'))
const containerRef = useRef<HTMLDivElement>(null);
const activateRef = useRef(false); // 用来判断当前组件是否需要被缓存
// 如果当前这个组件已经被缓存了 那就返回true 如果没缓存,可能是因为没被加载,返回false不缓存此组件
activateRef.current = activateRef.current || props.active
useLayoutEffect(() => {
if (!containerRef.current) {
return
}
if (props.active) {
containerRef.current.appendChild(targetElement)
} else {
try {
containerRef.current.removeChild(targetElement)
} catch (e) { }
}
}, [props.active])
return (
<>
<div ref={containerRef} />
{activateRef.current && ReactDOM.createPortal(props.children, targetElement)}
</>
)
}
export default Conditional
使用
<Conditional active>
<div /> {/* 被缓存的组件 */}
</Conditional>