一、基础 Hook(必掌握,官方核心基础)
- **
useState**保存组件状态,setter 触发重渲染。 - **
useEffect**处理副作用:请求、定时器、订阅、DOM 操作;挂载 / 更新 / 销毁执行。
jsx
scss
useEffect(() => {
// 执行副作用
const timer = setInterval(()=>{},1000)
return ()=> clearInterval(timer) // 清理函数
}, [依赖数组])
[]:仅挂载执行一次- 不写依赖:每次渲染都执行
- **
useContext**读取 Context 上下文,实现跨组件传参,替代多层 props 透传。
jsx
ini
const theme = useContext(ThemeContext)
- **
useRef**保存可变数据、获取 DOM,修改.current不触发渲染。
二、进阶状态 Hook(复杂状态管理)
1. useReducer
适合复杂状态、多状态联动、大量更新逻辑(表单、游戏状态)。相当于 useState 的加强版,类似简易 redux。
js
运行
scss
const [state, dispatch] = useReducer(reducer, initialState)
dispatch({type: "add"})
什么时候用:状态修改逻辑分散、根据不同 action 做不同处理。
2. useMemo
缓存计算结果,避免重复昂贵计算
js
运行
javascript
const total = useMemo(()=>{
return list.reduce((sum,item)=>sum+item.price,0)
}, [list]) // list不变,函数不会重复执行
⚠️ 只缓存返回值;不要盲目滥用。
3. useCallback
缓存函数本身,防止函数每次渲染重新创建 常搭配子组件 React.memo 使用,避免子组件无效重渲染。
js
运行
javascript
const handleClick = useCallback(()=>{
console.log('click')
}, [])
✅区分记忆:useMemo → 缓存值 useCallback → 缓存函数
三、DOM / 布局副作用 Hook
1. useLayoutEffect
执行时机早于 useEffect DOM 更新完成,但浏览器还没有绘制到屏幕前执行。适合:读取 DOM 布局、修改 DOM 样式(滚动、元素宽高)。
尽量优先 useEffect;只有需要同步操作布局时才使用 useLayoutEffect。
2. useImperativeHandle
配合 forwardRef,向父组件暴露自定义实例方法控制子组件对外暴露哪些 DOM / 方法,隐藏内部 API。
jsx
scss
useImperativeHandle(ref, () => ({
focus: () => inputRef.current.focus()
}))