React-router6.x最新版本keepAlive解决方案

2024-03-19
8183 分钟
...

前言

笔者百无聊赖,把项目中的react-router升级到最新版本来体验体验

"react-router": "6.8.1",
"react-router-dom": "6.8.1",

令我惊讶的是,最新版本的router官网甚至连翻译都没有,也许是我没找到,官网还是全英的

因为项目中react是18,router又升级到了6.8这就导致了以前用的react-router-cache-route不起作用了

于是笔者网上找了许久都没找到现成的解决方案,所以就只能自己边看文档边摸索了

最后算是解决了keepAlive,所以希望能帮助到遇到相同问题的同学

正文

说真的,router6.8真的变化很大,很多用法有实质性的改变,感觉router也在往拥抱函数式的路上渐行渐远啊。

先来看下以下代码,用于渲染两个页面A & B

function A() {
    const navigate = useNavigate();
    return <div>
        <h1 onClick={() => navigate('/b')}>A</h1>
        <input type="text" />
    </div>
}

function B() {
    const navigate = useNavigate();
    return <div>
        <h1 onClick={() => navigate('/a')}>B</h1>
        <input type="text" />
    </div>
}


const routes: RouteObject[] = [
    {
        path: '/a',
        element: <A />,
    },
    {
        path: '/b',
        element: <B />,
    }
]

const router = createBrowserRouter(routes, {
    basename: process.env.PUBLIC_URL
})


function App() {
    
    return (
        <Suspense fallback={<div />} >
            <RouterProvider router={router} />
        </Suspense>
    );
}

export default App;

个人认为不同点在于应用路由的方式 不同于之前的Switch route

而是采用了 createBrowserRouter RouterProvider useRoutes

具体的用法细节可以参考官方文档哈

上面的代码在页面上的效果是这样的:

我们可以实现A - B之间的切换 但是A& B页面的输入内容是没法保留的

所以我们需要实现keep alive 切换的同时保留我们在页面留下的痕迹

实现 KeepAlive

实现的关键在于router6.8 提供了useOutLet 让我们可以捕获匹配到的子元素

那么我们干脆自己存储子元素 再自行判断路由来做条件渲染就好了

由于要alive当前页面的元素,势必就只能采用样式隐藏的方式 来做 这也是当前社区主流的做法

所以我们根据上面的思路设计存储组件:

import { useUpdate } from "ahooks";
import { useEffect, useRef } from "react";
import { useLocation, useOutlet } from "react-router-dom";

function KeepAlive() {
    const componentList = useRef(new Map());
    const outLet = useOutlet();
    const { pathname } = useLocation();
    const forceUpdate = useUpdate();

    useEffect(() => {

        if (!componentList.current.has(pathname)) {
            componentList.current.set(pathname, outLet);
        }
        forceUpdate();
    }, [pathname]);

    return <div>
        {
            Array.from(componentList.current).map(([key, component]) =>
                <div key={key} style={{display: pathname === key ? 'block': 'none'}}>
                    {component}
                </div>
            )
        }
    </div>
}

export default KeepAlive;

原理很简单,使用map结构 缓存url -> outlet的映射 然后再循环列表渲染

keepalive组件做好了,我们需要调整routes的结构


const routes: RouteObject[] = [
    {
        path: "/",
        element: <KeepAlive />,
        children: [
            {
                path: '/a',
                element: <A />,
            },
            {
                path: '/b',
                element: <B />,
            }
        ],
    }
]

我们在顶层的父级路径使用,后续所有的路由组件都会应用到keep alive功能

现在再来看看效果吧~

所以,keepAlive并不复杂,如果遇到相同的问题,希望对大家能有点帮助吧

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
react2025-12-02
useEffect与useLayoutEffect对比
在 React Hooks 中, 和 都用于处理副作用逻辑,例如订阅、事件监听、DOM 操作等。但它们有着本质性的执行时机差异,这影响到页面渲染、布局抖动、性能表现等关键点。 1\. 执行时机的核心区别 在 React 的渲染流程中: 1. 渲染(Render phase) React 根据 state/props 计算 UI,生成虚拟 DOM,不访问真实 DOM。 2. 提交(Commit phase) React 将虚拟 DOM 变...
学习
react2025-08-03
在 React 中实现倒计时功能会有什么坑
倒计时 倒计时是一个非常常见的业务场景,但是在 React 中实现起来,却不算简单。 首先我们来看这段倒计时代码,它能否正常执行? 来看看实际表现效果 可以看到计时器在不断执行,但是 的值却没有变。 这是一个很经典的问题:React 闭包陷阱 。 我们来详细分析下: 的依赖数组 是空的,这意味着 effect 只会在组件挂载时执行一次,而不会在 状态更新时重新执行。所以 回调函数中捕获的 值始终是初始值 。 这个问题解决起来也很简单,有...
学习面试
react2025-07-30
React性能优化三剑客:memo、useMemo和useCallback详解
前言 在React开发中,性能优化是一个永恒的话题。今天我们就来深入探讨React提供的三个重要性能优化工具: 、 和 ,它们如何帮助我们构建更高效的React应用。 1\. 为什么需要性能优化? 🤔 React的核心机制是当组件的state或props发生变化时,组件会重新渲染。但有时这种重新渲染是不必要的: 父组件更新导致所有子组件重新渲染 ,即使子组件的props没有变化 复杂计算在每次渲染时重复执行 ,消耗大量资源 函数引用在...
学习面试
react2025-06-05
React 中 useDeferredValue 和 startTransition 的核心区别与使用场景
React 中 和 ,两者都用于优化性能,但适用场景和实现方式不同。 核心概念解析 1\. useDeferredValue:延迟值更新 作用 :告诉 React 延迟更新某个值 ,直到所有高优先级渲染任务完成。 适用场景 :当某个值的更新会触发计算密集型渲染(如复杂列表、图表),但需要优先保证其他高优先级 UI(如输入框)的响应。 机制 : 保持旧值显示,后台计算新值。 计算完成后,用新值更新 UI,期间允许用户继续交互。 示例 :...
学习
react2024-12-18
Antd 样式覆盖
&nbsp; 目前作者所在的业务正在升级 Antd5.0,不得不说 Antd5.0 真的太香了,但是由于团队的 UE 规范进行了大改版,Antd5.0 所有的 必须对齐最新的规范,因此就需要对 Antd5.0 组件做主题定制。 现状 目前针对项目中使用的 antd 高频组件进行了梳理,并且根据规范基于 design token 对这些高频组件进行样式定制,对于主题色、圆角、边框、字体等用户 高的主题都已经满足团队规范。 虽然 Desig...
学习
react2024-12-06
React 19 终于发布,一大波新功能正式升级
这篇文章主要介绍了 React 19 的新功能,包括 Actions 自动处理数据突变相关状态,新增的 useActionState、useFormStatus、useOptimistic 等 hook,新的 use API 读取渲染资源,新的 React DOM 静态 API 生成静态站点,以及 React 服务器组件中的 RSC 和 RSA 等内容。同时提到后续会分享针对旧版功能的优化和改良。 关联问题: React 19 性能如何...
学习面试

评论

请登录后发表评论

去登录
加载评论中...

目录