React搜索框实现防抖、onChange及清空
我们经常会用到搜索框元素,需求一般是这样的:
获取实时输入并请求结果渲染到列表,以及允许用户清空input框
这样需求在react里实现,需要考虑以下几点:
- 输入防抖
- 异步操作中获取onChange的input的值
- 将input的value设置为state的值,实现清空输入框
那么,我们首先把这个input元素写出来
// search.tsx
import React, { useState, useEffect, useContext } from 'react'
const Search: React.FC = (props: any) => {
const [listInput, setListInput] = useState({
text: '',
holder: '您要去哪儿',
focus: false,
suggestionIndex: 0,
suggestion: [
{text: '',list: []},
{text: '',list: []}
],
show: false,
suggestionNoResult: false
})
// 这里实行onChange
const addressOnchange: React.ChangeEventHandler<HTMLInputElement> = (e: React.ChangeEvent<HTMLInputElement>) => {
// 将input中的value拿去查询
// 实时设置value
setListInput({...listInput, text: e.target.value})
}
return (
<input type="text" value={listInput.text} placeholder={listInput.holder} placeholder-style="color:#B7B9BE;" onChange={(e) => addressOnchange(e) } />
)
}
这时候,我们将需求中的第三点,也就是允许用户清空输入框的基础已经实现了,清空的操作只需要
setListInput({...listInput, text: ''})
但是作为输入框,用户输入随时变化,如果根据这个变化频率来请求接口,不仅增加许多无谓的性能损耗,还可能把api搞崩,所以防抖是必须的。
// 由于实时设置input的value导致state刷新 初始化timeout一定要放在const Search的组件定义外部
let timeout: any
// 这里实行onChange
const addressOnchange: React.ChangeEventHandler<HTMLInputElement> = (e: React.ChangeEvent<HTMLInputElement>) => {
if (timeout) clearTimeout(timeout)
timeout = setTimeout(() => {
console.log(e.target.value)
// api request
}, 800)
}
就这样,我们就实现了防抖,但是细心的小朋友会发现一个问题,那就是e.target变成了空,拿不到了。
原来我们打印这个值是在异步函数里面执行,在react中,异步函数对函数事件访问需要使用
e.persist()
加上之后
const addressOnchange: React.ChangeEventHandler<HTMLInputElement> = (e: React.ChangeEvent<HTMLInputElement>) => {
e.persist()
setListInput({...listInput, text: e.target.value})
// 防抖
if (timeout) clearTimeout(timeout)
timeout = setTimeout(() => {
console.log(e.target.value)
// api request
}, 800)
}
就这样,我们完美实现了搜索框的防抖,异步请求及清空input需求的基础