背景
现在有一个需求,是在更新 Input 输入框时,搜索数据。
类似的功能图如下:
通过 react useEffect,简单的 demo 实现如下:
import { Input } from 'antd'
import { useEffect, useState } from 'react'
import './App.css'
function App() {const [val, setVal] = useState('')const onSearch = (val) => {console.log('搜索', val || '全部')}// 当 val 发生变化时,请求搜索数据useEffect(() => {onSearch(val)}, [val])return (<div className='App'><Input value={val} placeholder='请输入' onChange={(e) => setVal(e.target.value)} allowClear /></div>)
}
这时可以看到,首次进入页面,会发起 2 次查询全部的搜索数据请求,然后每次输入框更新,都会发起搜索数据的请求。
为了优化性能,我们可以在搜索数据时,加入防抖的逻辑,只有当输入操作停顿指定时间后,才发起搜索数据的请求。
lodash debounce + useCallback
引入 lodash 的 debounce 方法。
lodash_.debounce(func, [wait=0], [options=])创建一个 debounced(防抖动)函数,该函数会从上一次被调用后,延迟 wait 毫秒后调用 func 方法。
将 onSearch 方法用 lodash.debounce + useCallback 封装后,可以实现防抖效果。
const onSearch = useCallback(debounce((val) => {console.log('搜索', val || '全部')}, 500),[])
useDebounceFn
将上述 lodash debounce + useCallback 封装为自定义 Hooks useDebounceFn,useDebounceFn 将返回一个有防抖效果的函数。
useDebounceFn(fn1, options) 返回防抖 Hooks。
interface DebounceOptions {wait?: number
}
const useDebounceFn = (fn: (...args: any) => any, options: DebounceOptions) => {return useCallback(debounce(fn, options.wait), [])
}
const onSearch = useDebounceFn((val) => {console.log('搜索', val || '全部')},{wait: 500,})
useDebounce
在 useDebounceFn 基础上,实现 useDebounce,返回一个具有防抖效果的 state。
创建一个新 state,setState 用 useDebounceFn 封装,useDebounce(state, options) 返回防抖 state。
function useDebounce<T>(value: T, options: DebounceOptions) {const [debounced, setDebounced] = useState(value)const update = useDebounceFn((value) => {setDebounced(value)}, options)useEffect(() => {update(value)}, [value])return debounced
}
将 useEffect 的依赖项改成 useDebounce 返回的 state,同样可以实现搜索防抖:
const debounceVal = useDebounce(val, { wait: 500 })
const onSearch = (val: string) => {
console.log('搜索', val || '全部')
}
// 当 debounceVal 发生变化时,请求搜索数据
useEffect(() => {
onSearch(debounceVal)
}, [debounceVal])
useDebounceEffect
在 useDebounceFn 基础上,实现 useDebounceEffect,返回一个具有防抖效果的 useEffect。
创建一个新 state,setState 用 useDebounceFn 封装,依赖更新时防抖更新 state,新 state 更新时执行副作用,这时副作用就防抖执行了。
useDebounceEffect(effect, deps, options) 返回防抖 useEffect。
function useDebounceEffect(effect: EffectCallback, deps: DependencyList, options: DebounceOptions) {const [debounced, setDebounced] = useState({})const update = useDebounceFn(() => {setDebounced({})}, options)useEffect(() => {update()}, deps)useEffect(effect, [debounced])
}
将 useEffect 改成 useDebounceEffect,就可以实现搜索防抖:
useDebounceEffect(() => {onSearch(val)}[val],{ wait: 500 })
最后
整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享
部分文档展示:




文章篇幅有限,后面的内容就不一一展示了
有需要的小伙伴,可以点下方卡片免费领取
本文探讨了在React应用中优化Input搜索性能的需求,通过使用lodash的debounce与useCallback结合,实现防抖功能。进一步封装成自定义Hooks useDebounceFn、useDebounce和useDebounceEffect,分别返回防抖函数、防抖状态和防抖副作用。这些Hooks有助于减少不必要的搜索请求,提升用户体验。

4841

被折叠的 条评论
为什么被折叠?



