React18对接wujie碰到的问题与解决

最近有个需求要将项目作为一个模块集成到另一个系统中,那边采用wujie的方式对接我们这些接入的系统,我们作为wujie的子应用,也需要进行相应的改造。经过多天的改造以及联调,问题终于都解决了,现在就将碰到的问题记录一下,方便以后再碰到时查阅。

项目使用的模块:

模块版本
React18.2
Antd5.13.1
react-router-dom6.18.0
nodev18.19.
typescript4.9.5

@craco/craco

5.9.0

wujie的地址:无界 | 极致的微前端框架

问题一:运行模式选择了单例模式,但是菜单切换时,路由不能正常跳转到对应的组件

描述:集成到wujie主应用后,菜单是统一在主应用进行管理的,在切换菜单时,浏览器上地址发生了变化,但是子应用的路由就是不能正常跳转到对应的组件,经过多次测试验证,怀疑是单例模式的生命周期改造那一块代码出了问题,但是wujie官网上只有集成React17的案例,而React升级到18后组件的挂载和卸载方式都发生了变化。

React17wujie子应用的生命周期改造如下:

if (window.__POWERED_BY_WUJIE__) {
  window.__WUJIE_MOUNT = () => {
    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById("root")
    );
  };
  window.__WUJIE_UNMOUNT = () => {
    ReactDOM.unmountComponentAtNode(document.getElementById("root"));
  };
} else {
  ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
    document.getElementById("root")
  );
}

而React18之后,组件挂载方式发生了变化:

// React17
const root = document.getElementById("root");
ReactDOM.render(
      <App />,
      root 
    ); 


// React18
const container = document.getElementById("root") as HTMLElement;
const root = ReactDOM.createRoot(container);
root.render(
    <App />
);

组件卸载:

// React17
ReactDOM.unmountComponentAtNode(document.getElementById("root"))
 

// React18
root.unmount()

所以根据这些变化,写了React18的配合wujie生命周期的改造代码如下:

if (window.__POWERED_BY_WUJIE__) {
  const container = document.getElementById("root") as HTMLElement;
  const root = ReactDOM.createRoot(container);
  window.__WUJIE_MOUNT = () => {
    root.render(
      <App />  
    );
  };
  window.__WUJIE_UNMOUNT = () => {
    root.unmount();
  };
} else {
  const container = document.getElementById("root") as HTMLElement;
  const root = ReactDOM.createRoot(container);
  root.render(
    <App />
  );
}

本来以为很顺利,但是切换菜单时,就是不能路由匹配对应的组件,但是有一个很奇怪的现象是,刷新浏览器,路由就会正常跳转。被这个问题折腾了好久,主应用那边毕竟是别人开发,也没有时间帮忙排查,就让我自己一点点找。但是我自己测试验证,路由配置也没有问题。然后我打印useLocation(),发现点击菜单时,该值还是上一个菜单的值,和浏览器中的值不一样,刷新浏览器之后useLocation()打印的值就和浏览器一致了,所以怀疑是不是生命周期改造那块组件卸载有问题,组件没有正确卸载吗? 由于时间紧,就没有继续深入研究这个问题,而是换一种运行模式,改为了重建模式,发现切换菜单能正常匹配路由了,后面就改用这种运行模式了。

问题二:antd组件库Table组件的列筛选功能,鼠标点击输入框之后立马消失

描述:点击列上的检索图表,弹出输入框之后,鼠标点击输入框输入内容,正常是可以输入内容的,但是集成wujie之后,鼠标点击,输入框立刻消失,后来排查发现是wujie的通用问题,如下:

就是这个e.target的指向问题,后面在git上找到了解决方案,实际上wujie官网上也列举了,在左下角:

wujie-polyfill文档地址:无界 Polyfill | 极致的微前端Polyfill

在该文档中,插件里面有一个EvnetTargetPlugin插件就是解决这个问题的:

具体改造是在主应用进行改造的:

// 安装依赖包
npm i wujie-polyfill -S


// 下面这三种方式选一种即可

import { startApp } from 'wujie'
import { EventTargetPlugin } from "wujie-polyfill";

// 无框架
setupApp({
    name: '唯一id',
    url: '子应用地址',
    exec: true,
    el: '容器',
    sync: true
    plugins: [EventTargetPlugin()]
})

// vue
<WujieVue
  width="100%"
  height="100%"
  name="xxx"
  :url="xxx"
  :plugins=“[EventTargetPlugin()]”
></WujieVue>

// react
<WujieReact
  width="100%"
  height="100%"
  name="xxx"
  url="{xxx}"
  plugins="{[EventTargetPlugin()]}"
></WujieReact>


主应用改造之后,上述问题就完美解决了。

问题三:子应用使用window.innerHeight获取的浏览器视口高度变成了主应用的iframe的高度,而且随着浏览器高度缩放,该值不发生变化

描述:window.innerHeight的值需要跟随浏览器高度的缩放而改变,但是接入wujie之后,子应用打印的该值不会发生变化

但是我没有使用上面的方案,用的是document?.documentElement?.clientHeight来替代,具体代码如下:

 import { useEventListener } from "ahooks";


  // 初始高度,可以根据实际情况调整
  const [tableHeight, setTableHeight] = useState(window.innerHeight - 123);


  // 监听窗口大小变化,更新表格高度
  const handleResize = () => {
    setTableHeight(document?.documentElement?.clientHeight - 123);
  };
  useEventListener("resize", handleResize);

上面就是集成wujie碰到的问题以及采用的解决方案,如果各位有更好的解决方法,可以留言告知,不甚感谢!

  • 32
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值