- 如下代码,data数据超过2千条时,每次输入字符过滤时非常卡
option.props.children.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1 }/>
其原因: 每次输入变化,data就要从2000多条数据中过滤出目标元素,一过滤就导致AutoComplete下拉列表得变化,浏览器得重新绘制下拉列表的Dom,导致浏览器卡
解决办法一
采用防抖函数,在间隔时间内,连续输入字符串只在最后一个字符串发生时才触发事件(onChange默认输入内容已改变就触发事件)
- 防抖函数
let timer;export const debounce = (func, wait ) => { // let timer = 0; return function(...args) { if (timer) clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, wait); };};
- 使用AutoComplete使用防抖函数
办法一可以减少事件的触发,但是仍然无法避免一个问题,就是首次点击输入框的时候特别卡,因为这个时候2000多条数据要一次被渲染
然而,没有人会无聊到从2000多条数据滚动鼠标去查找自己的目标元素,都会通过输入关键字符去过滤查找 所以首次没必要加载这么多数据,可以默认截取原数据的前50条来显示即可 后面在输入框输入关键词后,将过滤好后的数据在赋给dataSource减少不必要的Dom渲染
解决办法二,防抖和过滤二合一解决
static getDerivedStateFromProps (props, state) { return{ originDataLists: props.originDataLists, currentDataLists: state.currentDataLists.length>0 ?state.currentDataLists : props.currentDataLists.slice(1,100) } }onChange = (value) => { const {originDataLists} = this.state const currentDataLists = originDataLists.filter(item = item.toUpperCase().includes(value.toUpperCase())) this.setState({currentDataLists});};render(){ const {currentDataLists} = this.state return()}