React搜索过滤时如何避免图片重复加载?
问题分析
当回退搜索内容时,searchResults数组的引用会发生变化(比如从过滤后的新数组切换回原memes数组,或切换到新的过滤结果数组),导致MemeFeed触发重渲染。即便Meme组件通过meme.id保证了组件复用,但如果没有做渲染优化,组件仍会重新执行,加上懒加载图片组件的内部逻辑,就会引发已加载图片的重复请求。
解决方案
方案1:用React.memo优化Meme组件
给Meme组件添加React.memo包裹,通过浅比较meme prop,仅当meme对象引用变化时才重渲染组件,避免不必要的重渲染触发图片重复请求:
import { memo } from 'react'; const Meme = memo(({ meme }) => { return ( <div className="memePost"> <LazyLoadImage src={meme.url} alt={meme.url} /> <a href={meme.url} download={meme.url} target="_blank" rel="noopener noreferrer" > Download </a> </div> ) });
方案2:在父组件用useMemo缓存搜索结果
调整状态管理逻辑,让父组件通过useMemo根据搜索词计算searchResults,相同搜索词对应的结果数组会被缓存,避免频繁的数组引用变化触发重渲染:
1. 父组件代码调整
import { useState, useMemo } from 'react'; const ParentComponent = ({ memes }) => { const [searchTerm, setSearchTerm] = useState(''); // 用useMemo缓存搜索结果,仅当memes或searchTerm变化时重新计算 const searchResults = useMemo(() => { if (!searchTerm.trim()) return memes; const searchArray = searchTerm.trim().replace(/-/g, '').split(' '); return searchAlg(memes, searchArray); }, [memes, searchTerm]); return ( <div> <SearchBar searchTerm={searchTerm} setSearchTerm={setSearchTerm} /> <MemeFeed memes={searchResults} /> </div> ) }
2. 调整SearchBar组件
不再接收memes和setSearchResults,改为接收searchTerm和setSearchTerm:
const SearchBar = ({ searchTerm, setSearchTerm }) => { const handleSubmit = (e) => e.preventDefault() const handleSearchChange = (e) => { setSearchTerm(e.target.value); } return ( <div> <form className="search" onSubmit={handleSubmit}> <input className="search-input" type="text" id="search" value={searchTerm} onChange={handleSearchChange} /> <button className="search-button">Hae</button> </form> </div> ) }
补充说明
- 方案1聚焦于
Meme组件的渲染优化,确保已加载的图片组件不会因父组件重渲染而重复执行加载逻辑。 - 方案2从根源上稳定
searchResults的数组引用,减少因数组变化触发的MemeFeed重渲染。 - 两个方案可以结合使用,达到最优的性能优化效果。
内容的提问来源于stack exchange,提问作者Ode
相关产品推荐
相关产品推荐

