React Hooks 最佳实践:从入门到精通
深入探讨 React Hooks 的使用技巧和常见陷阱,帮助你写出更优雅的 React 代码
·8 分钟·更新于 2025/01/12·前端开发
#React#Hooks#JavaScript
React Hooks 最佳实践:从入门到精通
自从 React 16.8 引入 Hooks 以来,函数组件已经成为 React 开发的主流方式。但是,如何正确使用 Hooks 避免常见陷阱,仍然是很多开发者面临的挑战。
useState 的使用技巧
1. 避免在循环、条件或嵌套函数中调用 Hook
这是 React Hooks 的第一条规则。Hook 必须在组件的顶层调用,以确保每次渲染时 Hook 的调用顺序保持一致。
// ❌ 错误示例
function UserProfile({ userId }) {
if (userId) {
const [user, setUser] = useState(null) // 不要这样做!
}
return <div>...</div>
}
// ✅ 正确示例
function UserProfile({ userId }) {
const [user, setUser] = useState(null)
if (!userId) {
return <div>请先登录</div>
}
return <div>...</div>
}2. 使用函数式更新避免闭包陷阱
当新的 state 需要基于旧的 state 计算时,应该使用函数式更新。
// ❌ 可能出现问题
const [count, setCount] = useState(0)
const increment = () => {
setCount(count + 1)
setCount(count + 1) // 这里不会让 count 增加 2
}
// ✅ 推荐做法
const increment = () => {
setCount(prev => prev + 1)
setCount(prev => prev + 1) // 这样可以正确增加 2
}useEffect 的深度应用
依赖数组的重要性
useEffect 的第二个参数是依赖数组,它决定了 effect 何时执行。
// ❌ 忘记添加依赖
useEffect(() => {
fetchUser(userId) // userId 应该在依赖数组中
}, [])
// ✅ 正确添加依赖
useEffect(() => {
fetchUser(userId)
}, [userId])清理副作用
不要忘记清理副作用,特别是在处理订阅、定时器等场景时。
useEffect(() => {
const timer = setInterval(() => {
console.log('tick')
}, 1000)
// 返回清理函数
return () => {
clearInterval(timer)
}
}, [])自定义 Hook:代码复用的利器
自定义 Hook 是 React 最强大的特性之一。它允许你将组件逻辑提取到可重用的函数中。
// 自定义 Hook:useLocalStorage
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key)
return item ? JSON.parse(item) : initialValue
} catch (error) {
console.error(error)
return initialValue
}
})
const setValue = (value) => {
try {
setStoredValue(value)
window.localStorage.setItem(key, JSON.stringify(value))
} catch (error) {
console.error(error)
}
}
return [storedValue, setValue]
}
// 使用自定义 Hook
function App() {
const [theme, setTheme] = useLocalStorage('theme', 'light')
return (
<div className={theme}>
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
切换主题
</button>
</div>
)
}性能优化技巧
使用 useMemo 缓存计算结果
const expensiveValue = useMemo(() => {
return computeExpensiveValue(a, b)
}, [a, b])使用 useCallback 缓存函数
const handleClick = useCallback(() => {
doSomething(a, b)
}, [a, b])总结
React Hooks 为函数组件带来了强大的能力,但也需要我们遵循一些规则和最佳实践:
- 始终在顶层调用 Hook
- 正确使用依赖数组
- 记得清理副作用
- 善用自定义 Hook 实现代码复用
- 适时使用性能优化 Hook
掌握这些技巧,你就能写出更加优雅和高效的 React 代码。