1. 思路对比
- Vue:
<keep-alive>
内部会缓存 vnode,不会销毁组件实例。 - React:默认组件卸载后状态就没了,需要我们自己“保留”组件实例。
2. React 实现方式
方式一:条件渲染 + CSS 隐藏
- 用
display: none
隐藏,而不是unmount
。这样组件不会被销毁。
function App() {
const [active, setActive] = React.useState("A");
return (
<div>
<button onClick={() => setActive("A")}>组件A</button>
<button onClick={() => setActive("B")}>组件B</button>
<div style={{ display: active === "A" ? "block" : "none" }}>
<ComponentA />
</div>
<div style={{ display: active === "B" ? "block" : "none" }}>
<ComponentB />
</div>
</div>
);
}
✅ 优点:简单
⚠️ 缺点:所有组件始终存在内存中,可能占用资源。
方式二:状态提升(保留子组件状态)
把子组件的状态放到父组件,用 props 传递,这样即使子组件卸载了,状态也不会丢失。
function ComponentA({ value, setValue }: { value: string; setValue: (v: string) => void }) {
return <input value={value} onChange={e => setValue(e.target.value)} />;
}
function App() {
const [active, setActive] = React.useState("A");
const [aValue, setAValue] = React.useState("");
const [bValue, setBValue] = React.useState("");
return (
<div>
<button onClick={() => setActive("A")}>组件A</button>
<button onClick={() => setActive("B")}>组件B</button>
{active === "A" && <ComponentA value={aValue} setValue={setAValue} />}
{active === "B" && <ComponentA value={bValue} setValue={setBValue} />}
</div>
);
}
✅ 优点:状态持久化,组件卸载也不丢失数据
⚠️ 缺点:需要手动管理状态
方式三:第三方库 react-activation
- 社区有库专门实现
keep-alive
功能,最常用的是react-activation
。
用法:
import { AliveScope, KeepAlive } from 'react-activation';
function App() {
return (
<AliveScope>
<KeepAlive>
<ComponentA />
</KeepAlive>
<KeepAlive>
<ComponentB />
</KeepAlive>
</AliveScope>
);
}
✅ 优点:和 Vue 的 keep-alive 几乎一致
⚠️ 缺点:引入第三方库
3. 总结
React 没有内置的
keep-alive
,但我们可以通过几种方式实现类似效果:
- 最简单的方法是条件渲染时用
display: none
隐藏而不是卸载;- 或者把子组件的状态提升到父组件,保证组件重挂载后状态不丢;
- 另外,社区有成熟库
react-activation
,能提供类似 Vuekeep-alive
的缓存机制。