useEffect 与副作用
约 390 字大约 1 分钟
布欧-Lewyon
2026-05-15
useEffect 基础
import { useState, useEffect } from 'react'
function Timer() {
const [seconds, setSeconds] = useState(0)
useEffect(() => {
const id = setInterval(() => {
setSeconds(s => s + 1)
}, 1000)
return () => clearInterval(id) // 清除函数(组件卸载时执行)
}, []) // 空依赖:只在组件挂载时执行
return <p>运行时间: {seconds}s</p>
}依赖数组
function UserProfile({ userId }: { userId: number }) {
const [user, setUser] = useState<User | null>(null)
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(setUser)
}, [userId]) // userId 变化时重新执行
return <div>{user?.name}</div>
}| 依赖数组 | 执行时机 |
|---|---|
| 无 | 每次渲染后执行 |
[] | 仅挂载时执行 |
[a, b] | a 或 b 变化时执行 |
清除函数
function SearchInput() {
const [query, setQuery] = useState('')
const [results, setResults] = useState([])
useEffect(() => {
if (!query) return
const controller = new AbortController()
fetch(`/api/search?q=${query}`, { signal: controller.signal })
.then(res => res.json())
.then(setResults)
.catch(err => {
if (err.name !== 'AbortError') console.error(err)
})
// 清除函数:组件卸载或 query 变化时取消请求
return () => controller.abort()
}, [query])
return <input value={query} onChange={e => setQuery(e.target.value)} />
}常见错误
// ❌ 错误:依赖数组未包含必要依赖
useEffect(() => {
document.title = `Count: ${count}`
}, []) // 缺少 count,lint 报错
// ✅ 正确
useEffect(() => {
document.title = `Count: ${count}`
}, [count])
// ❌ 错误:无限循环
useEffect(() => {
setCount(count + 1)
}) // 每次 setCount 触发渲染 → 再次执行 useEffect小结
useEffect处理副作用:数据请求、DOM 操作、定时器。- 依赖数组控制执行时机:空数组 = 挂载时一次;指定值 = 值变化时执行。
- 清除函数(return)用于取消订阅、清除定时器、中断请求。
- lint 规则
react-hooks/exhaustive-deps帮助发现遗漏依赖。
上一节:useState 与状态管理 下一节:useRef 与 DOM
