[ PROMPT_NODE_25250 ]
rerender-lazy-state-init
[ SKILL_DOCUMENTATION ]
## 使用惰性状态初始化
对于昂贵的初始值,请向 `useState` 传递一个函数。如果不使用函数形式,初始化程序会在每次渲染时运行,即使该值仅在首次使用。
**错误做法(在每次渲染时运行):**
tsx
function FilteredList({ items }: { items: Item[] }) {
// buildSearchIndex() 在每次渲染时都会运行,即使在初始化之后
const [searchIndex, setSearchIndex] = useState(buildSearchIndex(items))
const [query, setQuery] = useState('')
// 当 query 更改时,buildSearchIndex 会再次不必要地运行
return
}
function UserProfile() {
// JSON.parse 在每次渲染时都会运行
const [settings, setSettings] = useState(
JSON.parse(localStorage.getItem('settings') || '{}')
)
return
}
**正确做法(仅在首次渲染时运行):**
tsx
function FilteredList({ items }: { items: Item[] }) {
// buildSearchIndex() 仅在初始渲染时运行
const [searchIndex, setSearchIndex] = useState(() => buildSearchIndex(items))
const [query, setQuery] = useState('')
return
}
function UserProfile() {
// JSON.parse 仅在初始渲染时运行
const [settings, setSettings] = useState(() => {
const stored = localStorage.getItem('settings')
return stored ? JSON.parse(stored) : {}
})
return
}
当从 localStorage/sessionStorage 计算初始值、构建数据结构(索引、映射)、读取 DOM 或执行繁重的转换时,请使用惰性初始化。
对于简单的原始类型 (`useState(0)`)、直接引用 (`useState(props.value)`) 或廉价的字面量 (`useState({})`),函数形式是不必要的。