React里eltable自己变小的bug排查全过程

大家看 这神奇的BUG

现在里边这个表格是撑满这个弹框的

然后把弹框重新打开

大家看里边表格就变窄了

我们先来检查一下这个元素

现在这个表格的宽度大家看是

然后呢我们刷新一下

大概正常的情况下呢这个表格是

然后我们把它关闭

再重新打开

大概变成450了

怎么回事呢

我们先来看一下代码

他这个用的是react的

说实话react 我也不是很熟

没关系大家跟着我看就可以哈

我们先去看一下这个table的源码

这个react直接点不进去

所以呢我们需要自己去这个node_modules

里面去找到这个组件

在这里然后呢找到他这个table body

他看这块就有一个width等于this.bodyWidth

比如说他肯定是每一次展开的时候

这个值发生变化了

我们先来看一下这个值在哪设置的哈

哎在这里大家看

bodyWidth是从layout里面

取出来的

然后下面这点运算影响不大

那我们来看layout啊

layout他在这同级目录下有一个 table layout

然后呢这里边我们在搜bodyWidth

打开这个赋值 赋了一个

this.table的一个宽度

我们不管他再往下找

在这里

打开 body width

等于这两个值里边那个大的

body width

就是上面我们看到它取的就是这个el-table

table 的

这个整体的宽度

然后呢它还有一个变量body min width

它是怎么取的呢

大家看他在这啊

就是取他每一列的设置的这个width

或者每一列你给设置那个minWidth(之和)

啥意思呢

就是在这个表格里边大家看

他给每一列都设置

了一个minWidth

现在 minWidth minWidth

大家看!三列:150 、100 ,200 加一起

正好是那个

所以呢他在这我们可以断定

(二次打开的时候 ) 他在这取值的时候肯定是他这个

正好比他大

那为什么他会比他大呢

这个很容易我们试一下就知道了

因为他不是取的这个el-table的clientWidth吗

我们就取他的

clientWidth

大家看 现在是

我把它关闭

因为他是关闭的时候弹出的一瞬间吗

所以我们这个时候再获取一下

大家看这就是0了

也就是说他在隐藏的时候啊

取到的这个clientWidth是

所以呢他0一定是小于最小宽度450的

所以打开的时候

就被更新成450的宽度了

但问题是

他为什么要在这

调一下这个更新的组件呢

来看一下这个方法在哪调用的

大家看在这

其他的就没了

然后呢我们再看这个方法在哪调的

resizeListener 这个很正常

这个啊就是构造函数里边的一个监

加了一个监听

这个不管他

我们再找

componentDidMount

这估计是react的一些生命周期

挂载完之后的我们再来找

componentDidUpdate

估计就是走到这了

我们再来看应该就没有别的了

大家看 就回来了 所以

应该就是走在这

就是说他每次重新打开的时候

都走了这个方法

然后呢他这有个判断 大家看

看这个字面的意思

就是看这些属性是不是发生变化了

就说columns、style、className

这3个属性任意一个发生变化

他都会更新一下这个表格的一些

尺寸啊什么的

那现在的问题就

是我们这3个属性到底变没变

我们来看一下

我们选中这个 el-table

然后呢我们盯着这节点的这些属性

打开这个弹框大家看

大家看 没有变化对不对

我再关闭

也就是说 他任意一个属性都没有变化

包括style也没有变化

为什么他就会走这里呢

所以呢这就很奇怪

那这种情况呢

我们最好的方法就是

在这可以加一个输出

来调试一下

但是啊直接在这加输出是不好使的

这个我试过

但后来我找到了一个方法

分享给大家哈

就这样

他不是有这段代码吗

我们搜一下这段代码在哪呢

在页面上找network

然后刷新一下

把所有资源加载上以后啊

然后啊在这里用 command + option + F

调出来这个窗口

然后我们在这搜

粘过来直接搜哈

开始直接搜的话

他搜出来一个这个大家看TabeLayout.js

跟那个是一样的

这个我也试了他不走

后来我想是不是引号的问题

我就把这个单引号换成双引号

试了一下

就找到这个了

chunk-CADB....

那我们打开这个

然后呢在这右键 open in new tab

这样的话

就可以单独浏览这个js文件了

我们把这个文件名复制到这个vscode里

看有没有直接打开这个

大家看有这个,我最近打开过哈

如果没有打开过的话

直接在这找是没有的

大家可以直接在这里边一层一层去找

那我这个打开过

先不管它哈

我们在这打开它

然后呢还是找到这段代码

大家看

那这几个咱们都在这输出一下

打卡靠拢 style

然后再来一个拉丝内容

看到底是哪个属性他发生变化了

然后呢注意在这个文件里改的东西啊

每次他需要重启一下

我们重启一下

然后呢我们刷新一下

咱再搜一下这个

大家看,这console.log就加上了

然后呢我们在这再刷新

看下效果

大家看我打开它

先不管他清空然后关闭

大家看

关闭的时候他有一次是中间那个是true

我们再打开

他看还是中间那个是true

他就一直认为中间那个值,也就是说

这个style发生变化了

好那我们再来看

他为什么会认为style发生变化了

我们看下这里边他怎么写的

在这里他获取了最新的style的样式

然后获取了(pre嘛)上一次的样式

然后他俩做了一个

不等于的比较

我们把这一段代码啊都拿过去

放到这然后呢把这key改成("style")

(因为它认为style变了嘛)

我们把style拿过来

我们用 JSON.stringify

然后呢再来一个

这个 pre 的

然后后面就不要了

好我们再来试一下,注意重启一下

好我们来试一下啊先把这刷新一下

因为他可能有缓存

然后再来这刷新

清空一下

展开关闭我们再清空

最后我们再展开注意看啊

大家看,明明是一模一样的值

他就认为

发生变化了

那这是为什么呢我们来看一下这

他在写这个table的时候啊

这个style里边是这样写的

所以呢

他每次

这个地方

他都会认为这是一个新的对象

所以呢

他在这做这个属性比较的时候 大家注意看

因为他用的是这个

3个等号的这种比较所以呢他会认为

这块虽然值一样

但是他不是同一个对象了

所以就发生变化了

我们把它去掉试一下

不要任何的样式了

报错! 我们把这个也去掉吧!不要style了

刷新

大家看

这就没问题了

但是呢实际情况可能又需要配置样式

那怎么办呢

我们可以这样把这个样式啊

放到上面这个state里面

在这里比如说我们叫tableS tyle

哎把它拿这来

然后呢在下边我们用

this.state.tableStyle

好我们再刷新一下

大家看 没问题了这样就完美解决了

那还有一种方法呢

就是我们不用style了

把我们想写的样式封装成CSS

然后呢在这写className

这个是没有问题的

这个我试过

你怎么写

他都不会认为这个属性发生变化了

所以呢就不会有任何问题

最后更新于