背景
antd+react 项目里有个select,由于option数据量较大,目前采用的是后端默认返回第一页剩下的数据需要靠用户手动输入关键字来检索展示结果。
最近得到用户反馈:
当想要选择
单元
时,点击select出现内容后误以为展示的是全部结果( 实际只是前30条数据 ),但是却没有在这里找到他想选择的单元
。
有两种方案:
- 将下拉框变成输入框;没有关键字时不请求接口;将placeholder改成更具搜索引导性的语句。
- 给option做分页懒加载。
按照这数据量级果断选择了第二种方案,做懒加载;
过程
先查查antd的select部分文档
很好很好,就是我需要的,来试试
<Form.Item>
{getFieldDecorator('unit', {
rules: [
{
required: true,
message: '请输入单元',
},
],
})(
<Select
showSearch
allowClear
key="unit"
placeholder="请输入单元"
onFocus={() => handleSearch(‘unit’)}
onSearch={(val) => handleSearch('unit', val)}
onPopupScroll={(e) =>{console.log('滚动中...')}}
>
{unitList.map((item: any) => (
<Option
key={item.unitId}
value={item.unitId}
>
{item.unitName}
</Option>
))}
</Select>
)
<Form.Item>
但是发现滚动后并没有打印出滚动中...
。
猜想:难道是和form
有关?
于是在最最最最外层用antd最简单的例子写了个demo:
<Select defaultValue="lucy" onPopupScroll={(e) =>{console.log('滚动中...')}}>
<Option value="jack">Jack</Option>
<Option value="lucy">Lucy</Option>
<Option value="disabled" disabled>Disabled</Option>
....
<Option value="Yiminghe">yiminghe</Option>
</Select>
即使这么简单了!!!还是没有打印!!!没有执行回调!!!为什么没有触发呢??
搜索引擎搜了个遍,搜到的要不就是例子要不就是说antd版本过老不支持。。。我可是3.26.19
!!!antd对应版本文档上清清楚楚写着支持这属性。。
白纸黑字
猜想:难道是antd生成的option列表dom结构有些问题导致监听不到?
看了下生成的dom
ul外层的div
ul
这两个元素的overflow
都是auto
!!!!有没有可能是监听元素滚动的时候互相影响了导致没触发?
- 强制覆写 div 的样式
:global {
.ant-select-dropdown>div{
overflow: initial;
}
}
无事发生
- 强制覆写ul 的样式
:global {
.ant-select-dropdown-menu {
overflow: initial;
}
}
可以滚动!!
可见 antd 监听的中间这个div
的滚动!!!!
附一下代码
const handleScroll = (e)=>{
const { target } = e;
// 提前200到底的时候加载!
if (target.scrollTop + target.offsetHeight >target.scrollHeight - 200) {
console.log('开始懒加载!!');
}
}
<Form.Item>
{getFieldDecorator('unit', {
rules: [
{
required: true,
message: '请输入单元',
},
],
})(
<Select
showSearch
allowClear
key="unit"
placeholder="请输入单元"
onFocus={() => handleSearch(‘unit’)}
onSearch={(val) => handleSearch('unit', val)}
onPopupScroll={((e) => handleScroll(e,'unit'))}}
>
{unitList.map((item: any) => (
<Option
key={item.unitId}
value={item.unitId}
>
{item.unitName}
</Option>
))}
</Select>
)
<Form.Item>
结果
通过强行覆写antd样式解决了这个问题,后续科学上网在issue上也发现了它。
image.png
只能说!!确实很不负责!!!
另外想说虽然组件库超级多,拿过来就用真的很快,但是一旦出现问题排查起来还是很致命的。。尤其一些工程化的库 umi qiankun等等等等,只能说双刃剑吧。。。。