--- title: Use Lazy State Initialization impact: MEDIUM impactDescription: 每次渲染时浪费的计算 tags: react, hooks, useState, performance, initialization --- ## 使用惰性状态初始化 对于昂贵的初始值,向 `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({})`),则不需要函数形式。