搜索相关问题
背景:最近写项目时,原以为的按条件搜索发现了很多问题,比如没输入搜索条件,输入部分搜索条件,如何实时显示搜索数据等
搜索条件解决

搜索条件如图,最开始我想的是,每次搜索用filter筛选出来数据都匹配的数据就好了,但是搜索条件不一定有,或者只有一部分,这样的话,有的搜索条件取出来的值就是undefined,和哪一项都不会成功匹配也就是搜索不出来数据。
解决:
1 2 3 4 5 6
| const finds = products.filter((p: any) => { let c1 = name || p.name let c2 = others ? (others.indexOf('onsale') === -1 ? p.status : 1) : p.status let c3 = brand || [p.brand] return p.name.indexOf(c1) !== -1 && c2 === p.status && c3.indexOf(p.brand) !== -1 })
|
如果是undefined就和数据相等就好了,我这里只展示了对字符串和数组进行的搜索。
输入实时搜索
我想在输入商品名称时进行实时匹配,
1 2 3 4 5 6 7 8 9 10
| <Input placeholder='可输入商品名称查询' onChange={changeName} /> ... const changeName = (e: any) => { const proName = e.target.value const finds = products.filter((p: any) => { return p.name.includes(proName) }) setFindpros(finds) props.onChange && props.onChange(finds) }
|
每次输入改变时就进行一次查询,可是在我以为成功了的时候检测到了这样的问题,用中文输入法输入字符但是还没有点击文字时,value是还没有确定的那部分字符串,比如,想输入娃哈哈

但是此时搜索的确实wahah,这样就搜索不出来数据,怎么办呢?
解决:
加上判断,只有在输入框中没有英文字符时才进行搜索
1 2 3 4 5 6 7 8 9 10 11
| const changeName = (e: any) => { const proName = e.target.value var re = /[a-zA-Z]/ if (!re.test(proName)) { const finds = products.filter((p: any) => { return p.name.includes(proName) }) setFindpros(finds) props.onChange && props.onChange(finds) } }
|
更改后的代码如上,这样就不会出现输入一个汉字出现商品,打字过程商品消失的现象了。
再优化一下,用户的输入可能很快很频繁,虽然打字挺慢的,但是要是不停地输入数字,删除数字也会造成不小的性能损失,所以这里我们加上debounce进行优化。
在直接给Input的onChange上加防抖事件,是不生效的,查了一下资料,因为react采用的是合成事件的机制。
事件处理程序通过 合成事件(SyntheticEvent)的实例传递,SyntheticEvent 是浏览器原生事件跨浏览器的封装。SyntheticEvent 和浏览器原生事件一样有 stopPropagation()、preventDefault() 接口,而且这些接口夸浏览器兼容。
SyntheticEvent 是池化的. 这意味着 SyntheticEvent 对象将会被重用,并且所有的属性都会在事件回调被调用后被 nullified。 这是因为性能的原因。 因此,你不能异步的访问事件。
所以要拆分函数,这样处理才可以
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <Input placeholder='可输入商品名称查询' onChange={changeName} /> ... const debounceSearchName = (name: string) => { var re = /[a-zA-Z]/ console.log(name) console.log('debounce') if (!re.test(name)) { const finds = products.filter((p: any) => { return p.name.includes(name) }) props.onChange && props.onChange(finds) } } const changeName = debounce((e) => { debounceSearchName(e.target.value) }, 300)
|
大功告成,实现了搜索功能,通过输入商品名称的实时搜索,加上了防抖,小小的得意。