ReactSearchAutocomplete状态异常:列表项仅在下次搜索时更新
问题原因
你这问题出在ReactSearchAutocomplete的onSearch回调不是用来做异步数据请求的。组件会在onSearch执行完立刻渲染,而异步fetch请求完成后调用setNamesList时,组件已经走完了当前渲染周期,导致这次的结果要等下一次输入才会显示。另外还没处理多请求的竞态问题——快速输入时,旧请求可能晚于新请求返回,会覆盖正确结果。
解决代码
调整逻辑,改用onChange监听输入,自己处理异步请求和竞态保护:
import { useState, useCallback, useRef } from 'react'; import ReactSearchAutocomplete from 'react-search-autocomplete'; const SearchBar = () => { const [namesList, setNamesList] = useState([]); const [searchTerm, setSearchTerm] = useState(''); // 用ref存最新请求的ID,防止旧请求覆盖新结果 const latestRequestId = useRef(0); // 封装搜索请求,带竞态保护 const fetchSearchResults = useCallback((term) => { if (term.length < 2) { setNamesList([]); return; } const requestId = ++latestRequestId.current; let queryString = "url/api/search/" + term; if (isDev) { queryString = "http://localhost:3001/search/" + term; } fetch(queryString) .then((response) => response.json()) .then((json) => { // 只处理最新的请求结果 if (requestId !== latestRequestId.current) return; const searchResults = json.map((o) => ({ id: o.name, name: o.name })); setNamesList(searchResults); }) .catch((error) => console.error(error)); }, []); // 监听输入变化,触发搜索 const handleInputChange = useCallback((term) => { setSearchTerm(term); fetchSearchResults(term); }, [fetchSearchResults]); return ( <div className="search-bar"> <ReactSearchAutocomplete items={namesList} onChange={handleInputChange} autoFocus={true} inputDebounce={100} showNoResults={false} value={searchTerm} /> </div> ); }; export default SearchBar;
核心修改说明
- 换用
onChange替代onSearch:onSearch是组件用来同步过滤已有数据的回调,onChange才是监听用户输入的正确事件,适合触发异步请求。 - 添加竞态保护:用
useRef记录请求ID,确保只有最后一次请求的结果会更新状态,避免快速输入时旧请求覆盖新结果。 - 绑定
value属性:把searchTerm状态绑定到组件的value,保证输入框值和外部状态一致,避免组件内部状态和外部状态脱节。
内容的提问来源于stack exchange,提问作者Dportology
相关产品推荐
相关产品推荐

