如何在React中正确使用debounce实现搜索输入防抖,避免频繁调用接口
React输入框防抖搜索实现方案
问题根源
- 前两种写法每次触发逻辑时都会创建全新的防抖函数实例,且创建后没有主动调用返回的防抖函数,导致内部逻辑永远不会执行,防抖规则完全失效。
- 第三种写法中useRef保存的防抖函数捕获了初始渲染时的
movieSearchString闭包值,后续state更新时函数内部读取的始终是旧值,因此无法输出最新的搜索字符串。
实现代码
import { debounce } from 'lodash' import { useState, useRef, useEffect } from 'react' function App() { const [movieSearchString, setMovieSearchString] = useState('') // 复用同一个防抖函数实例,接收搜索字符串作为入参规避闭包问题 const debouncedFetch = useRef(debounce((searchStr) => { console.log('deb: ' + searchStr) const params = { apikey: 'somekey' } if (searchStr.length > 2) { params.search = searchStr // 此处写实际的API请求逻辑即可 } }, 1000)).current const movieInputChangeHandler = string => { console.log('onMovieInputChange', string); setMovieSearchString(string) // 调用防抖函数,传入最新输入值 debouncedFetch(string) } // 组件卸载时清理定时器,避免内存泄漏 useEffect(() => { return () => debouncedFetch.cancel() }, [debouncedFetch]) const providerValue = { moviesList: moviesList, movieSearchString: movieSearchString, } return ( <MoviesContext.Provider value={providerValue}> <div className="App d-flex flex-column px-4 py-2"> <SearchBar onMovieInputChange={movieInputChangeHandler} /> ...Rest of the content </div> </MoviesContext.Provider> ); }
内容的提问来源于stack exchange,提问作者Igal
相关产品推荐
相关产品推荐

