React 中如何避免不必要的重渲染?
1. React.memo(组件级记忆)
const Child = React.memo(({ data }) => {
console.log('Child render')
return <div>{data.name}</div>
})
// 只有 data 变化时才重渲染2. useMemo / useCallback
function Parent({ items }) {
const [filter, setFilter] = useState('')
// ✅ 缓存计算结果
const filtered = useMemo(() => {
return items.filter(item => item.includes(filter))
}, [items, filter])
// ✅ 缓存函数引用
const handleClick = useCallback(() => {
setFilter('')
}, [])
return <Child data={filtered} onClick={handleClick} />
}3. 状态下放
将频繁变化的状态隔离到小组件中:
// ❌ input 变化导致整个组件重渲染
function App() {
const [text, setText] = useState('')
const [data, setData] = useState([])
return (
<>
<input value={text} onChange={e => setText(e.target.value)} />
<ExpensiveList data={data} />
</>
)
}
// ✅ 隔离状态
function App() {
const [data, setData] = useState([])
return (
<>
<SearchInput />
<ExpensiveList data={data} />
</>
)
}
const SearchInput = React.memo(() => {
const [text, setText] = useState('')
return <input value={text} onChange={e => setText(e.target.value)} />
})4. 虚拟列表
// react-window
import { FixedSizeList } from 'react-window'
const Row = ({ index, style }) => (
<div style={style}>Row {index}</div>
)
<FixedSizeList height={600} itemCount={10000} itemSize={35}>
{Row}
</FixedSizeList>5. 懒加载
const LazyComponent = React.lazy(() => import('./HeavyComponent'))
<Suspense fallback={<Spinner />}>
<LazyComponent />
</Suspense>6. key 优化
// ❌ 用 index 做 key(列表变化时性能差)
{items.map((item, index) => <Item key={index} data={item} />)}
// ✅ 用唯一 ID 做 key
{items.map(item => <Item key={item.id} data={item} />)}7. CSS 替代条件渲染
// ❌ 频繁挂载/卸载
{isVisible && <HeavyComponent />}
// ✅ 用 CSS 隐藏(保持挂载状态)
<HeavyComponent style={{ display: isVisible ? 'block' : 'none' }} />8. React 18 并发特性
// useTransition:将低优先级更新标记为可中断
const [isPending, startTransition] = useTransition()
const handleChange = (e) => {
setInputValue(e.target.value) // 高优先级:立即更新输入框
startTransition(() => {
setSearchResults(search(e.target.value)) // 低优先级:可中断
})
}性能检测
- React DevTools → Profiler
<Profiler>组件- Chrome DevTools → Performance