如何解决React搜索框使用useState、useEffect时的异步行为问题
问题产生原因
1. 执行时序不匹配
React 中 useEffect 的执行时机是组件完成渲染、DOM 已经更新到页面之后,你的过滤结果赋值逻辑放在 useEffect 里,天然存在时序差:
- 输入字符触发
setState后,React 会先触发组件重新渲染 - 渲染阶段读取的
available还是上一次useEffect执行后的旧值,本次的过滤逻辑还没有执行 - 本次渲染完成后,
useEffect才会运行,把最新的过滤结果赋值给available,但修改普通变量不会触发组件重渲染,新的过滤结果没办法立刻同步到页面 - 第二次输入字符触发新的重渲染时,才会读到上一轮
useEffect存储的过滤结果,看起来就比输入慢了一拍
2. 状态管理逻辑错误
你把过滤结果 available 声明成了全局普通变量,不属于 React 的状态管理体系,修改它不会触发组件重渲染,就算 useEffect 里更新了它的值,页面也不会自动刷新。
可选修复方案
不需要用 useEffect 处理过滤逻辑,直接在渲染时基于当前搜索词实时计算过滤结果即可,性能损耗完全可以忽略:
import React, {useState} from "react"; const array = [ { key: '1', type: 'planet', value: 'Tatooine' }, { key: '2', type: 'planet', value: 'Alderaan' }, { key: '3', type: 'starship', value: 'Death Star' }, { key: '4', type: 'starship', value: 'CR90 corvette' }, { key: '5', type: 'starship', value: 'Star Destroyer' }, { key: '6', type: 'person', value: 'Luke Skywalker' }, { key: '7', type: 'person', value: 'Darth Vader' }, { key: '8', type: 'person', value: 'Leia Organa' }, ]; const Setup = () => { const [searchKey, setSearchKey] = useState(''); // 渲染时直接计算过滤结果 const showList = searchKey ? array.filter(item => item.value.startsWith(searchKey)) : array; return <> <input value={searchKey} onChange={e => setSearchKey(e.target.value)} type="text" className="form" /> {showList.map(a => ( <Data id={a.key} key={parseInt(a.key)} value={a.value} type={a.type}/> ))} </> } const Data = (props) => { return <> <div> <p>{props.value}</p> </div> </> } export default Setup;
内容的提问来源于stack exchange,提问作者ali varaste pour
相关产品推荐
相关产品推荐

