React空搜索词时Filter不返回数据及useMemo警告问题
问题原因
- 核心问题是
useMemo依赖数组缺失data字段:组件首次渲染时,data是useState定义的初始空数组,Sanity接口请求是异步执行的,等接口返回数据触发setData更新data时,useMemo因为依赖列表里只写了searchTerm,不会重新执行计算逻辑,一直返回首次渲染时拿到的空数组,所以空搜索词下也展示不出数据。之前用本地静态JSON时,数据是同步导入的,首次渲染时data就已经是完整值,所以旧逻辑能正常运行。 - 控制台抛出的Hook依赖警告就是直接提示这个问题,另外你的过滤逻辑里解构的
id字段和Sanity返回的_id字段名不匹配,后续执行搜索时也会出现逻辑异常。
修复代码
直接替换对应逻辑即可:
const [data, setData] = useState<any[]>([]) useEffect(() => { sanityClient.fetch(`*[ _type == "positions"] { _id, category, type, position, location, }` ).then(result => { setData(result) }) }, []) const [searchTerm, setSearchTerm] = useState<string>(""); const filteredPositions = useMemo(() => { if (!searchTerm) return data; return data.filter(({ _id, ...other }) => { const lowerCasedSearchTerm: string = searchTerm.toLowerCase(); return Object.values(other) .map((v: any) => typeof v === 'string' ? v.toLowerCase() : '') .some((v: any) => v.includes(lowerCasedSearchTerm)); }); // 补全data依赖 }, [searchTerm, data]); // 渲染部分保持原有逻辑即可 {filteredPositions?.map((position: any) => ( <div key={position._id || position.position}> <SinglePosition category={position.category} type={position.type} position={position.position} /> </div> ))}
修复说明
- 把
data加入useMemo依赖数组后,data从接口拉取更新时会自动触发过滤逻辑重新计算,空搜索词下会直接返回最新的完整接口数据,控制台的Hook警告也会同步消除。 - 把过滤逻辑里解构的
id改为Sanity实际返回的_id,避免把_id字段纳入搜索匹配范围。 - 新增了值类型判断,避免字段值为非字符串类型(如null、数字)时调用
toLowerCase()抛出运行时错误。 - 渲染列表的key优先用Sanity返回的唯一
_id,避免position字段重复时出现React渲染警告。
内容的提问来源于stack exchange,提问作者Julia Schafer
相关产品推荐
相关产品推荐

