2024-11-16 小汇总
1. navigator.onLine 可能不准确
最近有用户反馈页面数据加载异常,UI加载出来了,但是页面中的表格数据是空的,但是周围同学一个也复现不出来,看用户演示,切到那个页面时,页面并没有出现loading,看着像是没有调接口。打开用户控制台,发现确实没有调接口。
接着看接口调用逻辑,很直白的调用方式,怎么会不调接口!?排查陷入迷茫状态。晚上下班想了想觉得逻辑写的是没毛病的,难道是接口调用用的React-Query这个库有问题?带着疑惑,来到github上react-query的官方仓库。翻了翻issue,发现有一条可疑的:
https://github.com/TanStack/query/issues/5679
问题描述跟我遇到的情况很相似,看了下面的回复,似乎是Mac电脑的chrome存在的一个bug:

来到chromium的bug页面:navigator.onLine returns false even though there is internet connectivity,下面回复有用react-query时出现的问题。

react-query v4版本内部使用了navigator.onLine这个浏览器API,用于判断当前网络环境,默认情况下如果当前网络是断开的,则不会调用接口。

那是不是这个问题引起的呢?目前没法排查出来,只能等有人再次反馈时把他的控制台打开,看看navigator.online的值是不是有问题。不过我可以先把这个问题修了,React-Query中有一个networkMode配置(默认值是online,有网络连接才会触发查询/突变),我将它配置成always,这样会忽略在线/离线状态,当网络异常时也会调接口。
幸运的是,在改动代码上线之前,组里有个同学也出了相同的问题,最后确认是navigator.online不对引起的。
2. svgr 更改图标大小问题
svgr是一个很好用的插件,它可以把SVG文件转成组件,在项目中直接引入使用。比如在React项目中,把svg文件直接引入作为icon图标使用:
import { ReactComponent as FolderOutlined } from '@/icons/folder-outlined.svg';
const App = () => {
return (
<div>
<FolderOutlined />
</div>
);
}
当我想给图标更改大小时,发现设置后的样式有问题。
<FolderOutlined width={24} height={24} />
检查元素看了对应的HTML,发现svg的viewBox没了。本来文件里的viewBox好好的,经过svgr后就没了。
当svg中的viewBox没有指定时,他会默认与viewport相同,viewport就是我们设置的width和height。viewport为24*24的大小,viewBox将是0 0 24 24,viewBox属性定义的是画布上可以显示的区域:从 (0,0) 点开始,24宽*24高的区域。也就是两者刚好1:1。svg元素里面的子元素path、rect等它们的坐标也会跟着缩放,1:1意味着坐标没发生变化,因此UI上绘制区域(原始的viewBox)如果很大就会展示不全,如果绘制区域(原始的viewBox)比viewport小,就会出现图标大小没变,svg整体区域(viewport区域)变大了。
如果原始的viewBox没被移除,就不会有这个问题,比如原始的viewBox为0 0 12 12,viewport是24x24,这个12*12的区域,会放到24*24的画布上显示,形成放大两倍的效果。
后来也是看了svgr的官方仓库找到了解决办法,相关bug链接:Preserving viewBox #18

配置完成后,看到viewBox没有丢失,问题也就解决了。我项目中用的svgr是比较老的版本了,新版本应该没有这个问题了。
3. 其他一些小问题
- React 中是不支持给内联样式添加
!important标记的,下面的写法将不生效。
<div style={{ fontSize: '20px !important' }}>
Hello
</div>
相关bug链接:Support !important for styles? #1881
- 在使用
@testing-library/react这个库写一些UI测试用例时,如果我们的测试用例涉及到scrollHeight/clientHeight等DOM相关的API时,需要怎么测试?
因为jsdom不支持布局,像这样的测量值将始终返回0。答案是自己模拟数据。
相关bug:scrollHeight/clientHeight for an element is always zero #353
相关文档:Testing element dimensions without the browser
- 依赖报错问题
最近用了一个三方包A,A包里依赖了很多其他三方包,而这些其他三方包好多都依赖一个B包,有些三方包规定B包的版本需要是0.x,但问题是B包连正式版都还没有,只有beta版本。因为找不到B包的正式版本,下载依赖时总是会报错。但我们在项目中需要使用A这个包,他比较复杂且重要,目前卡在了安装环节。
我们是知道B这个包用最新的beta版本就可以的,那些第三方包是版本依赖书写的有问题。需求紧急,只好使用overrides这个配置了,它是将依赖项树中的包替换为其他版本或完全替换成其他包的方法。
如果你需要对依赖项的依赖项进行特定更改,例如将依赖项的版本替换为已知的安全版本,或者确保在任何地方都使用相同版本的包,则可以添加这个配置。
最后我们决定在package.json中增加这个配置,问题得以解决。
{
"overrides": {
"B": "0.0.1-beta.144"
},
}
- 快速找到组件对应代码
项目比较大,对一个没新接触的模块或者很久没参与过的模块改需求或者修复bug,先去找到这个模块在哪可能就比较麻烦。有没有什么办法可以快速定位到代码在那个文件夹里?
最原始的办法可能就是利用页面上的文案全局进行搜索,如果文案比较特别那还是很容易定位到的,如果文案都差不多,或者有些组件写的很像,一搜可能出现好多个结果,这就有点麻烦了,可能需要改点UI先试一下,看页面上有没有反应。
另一种办法是使用插件,chrome插件商店有一个LocatorJS插件,在开发环境下,可以快速定位到代码对应的文件。

以React项目为例,使用这个插件之前你最好先安装一下React-Dev-Tools这个浏览器插件,不然可能定位不出来。
安装完后,启动本地开发环境,Mac上使 用Option+鼠标点击快捷键就可以定位组件了,Window则使用Alt+鼠标点击快捷键。