2.0 KiB
2.0 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| Use Lazy State Initialization | MEDIUM | 每次渲染时浪费的计算 | react, hooks, useState, performance, initialization |
使用惰性状态初始化
对于昂贵的初始值,向 useState 传入一个函数。不使用函数形式时,初始化器会在每次渲染时运行,尽管该值只使用一次。
错误做法(每次渲染都运行):
function FilteredList({ items }: { items: Item[] }) {
// buildSearchIndex() 在每次渲染时都运行,即使是在初始化之后
const [searchIndex, setSearchIndex] = useState(buildSearchIndex(items))
const [query, setQuery] = useState('')
// 当 query 变化时,buildSearchIndex 会再次不必要地运行
return <SearchResults index={searchIndex} query={query} />
}
function UserProfile() {
// JSON.parse 在每次渲染时运行
const [settings, setSettings] = useState(
JSON.parse(localStorage.getItem('settings') || '{}')
)
return <SettingsForm settings={settings} onChange={setSettings} />
}
正确做法(仅运行一次):
function FilteredList({ items }: { items: Item[] }) {
// buildSearchIndex() 仅在初始渲染时运行
const [searchIndex, setSearchIndex] = useState(() => buildSearchIndex(items))
const [query, setQuery] = useState('')
return <SearchResults index={searchIndex} query={query} />
}
function UserProfile() {
// JSON.parse 仅在初始渲染时运行
const [settings, setSettings] = useState(() => {
const stored = localStorage.getItem('settings')
return stored ? JSON.parse(stored) : {}
})
return <SettingsForm settings={settings} onChange={setSettings} />
}
当从 localStorage/sessionStorage 计算初始值、构建数据结构(索引、映射)、从 DOM 读取或执行繁重的转换时,请使用惰性初始化。
对于简单的基本类型(useState(0))、直接引用(useState(props.value))或廉价的字面量(useState({})),则不需要函数形式。