时间:2020/04/26 ,转载请注明出处。
写在前面
antd团队于2020年2月发布了酝酿已久的antd@4.0版本,对样式的调整、部分组件逻辑的重构都进行了较大改动,本文针对Table的rowKey属性重构作分析。
由一个mistake带来的思考
在数据治理模块的表格中使用了Table点击表格行进而选中该行的功能¹(非checkbox,点此查看官方demo),升级4.0后发现被选中表格行的className缺少了 ant-table-row-selected,导致交互效果失效。因为升级前后代码未作变动却出现问题,antd官方也并未声明该部分的改动,反复排查也没有找到问题所在。
后来意识到因为rowKey属性具有默认值"key",在不做显式设置的情况下,组件对此无感知,antd未做声明可能是因为该功能不会显式地对组件的使用产生影响,而此处出错的原因是我将rowKey错误地显式设置成"id"(dataSource中record的唯一主键是"key",与"id"不一致,导致错误)。有意思的是v3.x竟然没报错,并且可以正常使用。基于此疑惑与不解,我去翻看了源码,探究rowKey属性值究竟会否以及如何影响样式的变化。
在源码的对比中发现问题所在
借助VSCode的gitlens扩展²,快速定位到了Table@4.x中对rowKey属性的changelog。
发现antd对Table进行了大量样式上的改写,其中在PR(#19678)³中新增加了一个用于修改 rowClassName 的新方法 internalRowClassName ⁴。
在这个方法中,通过 getRowKey 获取正确的rowKey值,为选中行添加类名 ant-table-row-selected 从而实现选中行的底色效果。而 getRowKey 方法通过Table的rowKey属性值(默认为"key")去获取record["key"]的值,从而返回正确的key值⁵。所以当rowKey属性不显式设置或设置为正确的值(record的唯一主键)时,getRowKey方法可以返回正确的值,从而为row添加类名。但如果rowKey设置错误,则 getRowKey 返回undefined,那么 internalRowClassName 方法无法为row添加 ant-table-row-selected 类名。
由此看到,4.0版本中要求rowKey属性必须传入正确的值。那么为什么*rowKey传入错误的值在3.x版本中却没有报错呢?*
带着疑问,我将antd切到了branch@3.x-stable分支中再次查看getRowKey方法,发现 3.x中 getRecordKey 的返回值并不会受 rowKey 被错误设置的影响,它永远可以返回一个正确可用的key值⁶,因此不会出现上述问题。
真相大白。
如此一来,antd@3.x中rowKey属性的值实质上并不会对组件的使用产生报错性的影响(但会抛出warning),这也就解释了开篇中该mistake的问题所在。4.x对rowKey属性的改写以及rowClassName方法的新增,优化了Table组件的正确合理使用。antd将该PR定性为重构(Refactoring)⁷。