搜索相关

搜索相关问题

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

搜索条件解决

s
搜索条件如图,最开始我想的是,每次搜索用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是还没有确定的那部分字符串,比如,想输入娃哈哈
s
但是此时搜索的确实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防抖问题

在直接给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)

大功告成,实现了搜索功能,通过输入商品名称的实时搜索,加上了防抖,小小的得意。

上一篇

react-router需要了解