告别keepalive,使用ReactRouter6原生组件实现状态保留的多标签微前端

本文探讨如何在不依赖框架插件或额外库的情况下,使用ReactRouter6原生组件实现多标签状态保留的微前端。作者通过实践提出多标签的重要性和现有解决方案的不足,并详细阐述了实现多标签的关键点,包括组件获取、UI原生tab组件的使用以及React Context的本质。文章总结了ReactRouter6的优势,并指出Context在React中的重要地位。
摘要由CSDN通过智能技术生成

产品演示

AntdFront-基于recoil、react-router原生组件搭建按钮级权限多标签微前端模板

一、引言

从Jquery、Extjs等JS UI库 的mvc时代过来的程序猿,多标签那会从来不是个问题。到react的csr项目发现都是清一色基于react-router单页应用,而现存的多标签解决方案都要么依赖框架加插件(umi-plugin-keep-alive)的加持,要么依赖额外的库(react-activation、react-keepalive-router等)。上框架心里接受不了,因为框架往往是基于当下技术的工程最佳实践,对于技术变化迅速的前端领域,入坑后要学不动了往往就意味着被后浪的洪流淘汰。不上框架,上额外库,又得学习一大堆看的一脸懵逼的晦涩概念。只基于react-router和原生组件来实现多标签效果,市场上没有解决方案。

笔者之前在webpack搭建的AntdFront 中,只采用路由算法也实现了多标签效果。于是心中就产生了很大的疑惑,既然react-router 可以获取到具体的组件,组件都拿到了,多标签这么困难么?

AntdFront定位是实验性的按钮级权限多标签微前端模板,自己挖的坑,还得自己填。本文就围绕该项目 2.0版基于路由的多标签微前端实践过程中的几个关键问题,谈谈自己的理解和心得体会。

二、实践过程中的几个关键问题

1.为什么要多标签

多标签首先得能状态保留才有意义,是个用户体验问题。因为多标签,用户就可以一边上传文件,一边填写表单,妈妈再也不用担心用户的某些误操作导致表单重填的问题。两功能页面间可以做到互不干扰,且对于一些临时数据不需要额外的数据持久化逻辑,解放开发者的心智大脑。

2.为什么要router

antdFront 在1.0版中,只采用路由算法实现的多标签,在实践过程中,没有正经的路由,导航新的URL就得通过一些莫名奇妙的约定函数来实现。对于开发者说,都是额外的心智负担。最终放弃该方案的理由还是嵌套路由。将url 手工对应到组件还挺好实现,但是要对应到组件里的组件,且让组件的工程学开发人性化就有点困难了。好在有了react-router6,让嵌套路由变得不在晦涩。

3.现存解决方案 keepalive的缺点

现存react的keepalive是一套缓存方案,缓存的页面是无法进行交互的。也就是解决了用户某些误操作导致表单重填,额外的数据持久化逻辑的问题。但是没有解决一边上传文件,一边填写表单的问题。

其次引入keepalive,需要额外学习一大堆概念和用法限定。react的keepalive非官方特性,往往由个人团队开发,API不稳定。造成后期升级代码维护成本增加。

4.实现多标签的关键点是什么

1、拿到经路由算法筛选后的组件。

react-router6 是 react-router与 reach-router的 合并版本,是大致借鉴了reach-router的成功实践而对react-router的重构。它非常巧妙的使用context,利用 useOutlet 接口拿到不同层级的路由嵌套组件,非常完美的解决了嵌套路由的开发体验问题。下面tabRoute.jsx核心代码为例:

import {
    useState } from "react";
import {
    Tabs } from "antd";
import {
    useOutlet,useNavigate,useLocation,generatePath,useParams } from "react-router-dom";
import {
    usePersistFn, useCreation } from "ahooks";
import memoized from "nano-memoize";
import {
    i18n } from "@lingui/core";

const {
    TabPane } = Tabs;

const getTabPath = (tab) => {
   
  return generatePath(tab.location.pathname,tab.params)
}

// tab的select key = location.pathname + , + matchpath 
// matchpath为 config里配置的路由路径
// 以此解决 微端情况下 tab 的 key 相同导致页面可能丢失的问题。
const generTabKey = memoized((location,matchp
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值