React Hooks 是 React 16.8 引入的新特性,它让函数组件也能拥有状态和生命周期。本文将深入讲解 React Hooks 的使用方法和最佳实践。
useState - 状态管理
useState 是最基础的 Hook,用于在函数组件中添加状态:
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
)
}
useEffect - 副作用处理
useEffect 用于处理副作用,如数据获取、订阅、DOM 操作等:
import { useState, useEffect } from 'react'
function UserProfile({ userId }) {
const [user, setUser] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
setLoading(true)
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => {
setUser(data)
setLoading(false)
})
// 清理函数
return () => {
// 取消请求等清理操作
}
}, [userId]) // 依赖数组
if (loading) return <div>Loading...</div>
return <div>{user.name}</div>
}
useContext - 上下文共享
useContext 用于跨组件共享数据:
import { createContext, useContext } from 'react'
const ThemeContext = createContext('light')
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
)
}
function Toolbar() {
const theme = useContext(ThemeContext)
return <div>Current theme: {theme}</div>
}
useCallback 和 useMemo
这两个 Hook 用于性能优化:
- useCallback:缓存函数引用
- useMemo:缓存计算结果
const memoizedCallback = useCallback(() => {
doSomething(a, b)
}, [a, b])
const memoizedValue = useMemo(() => {
return computeExpensiveValue(a, b)
}, [a, b])
useReducer - 复杂状态管理
当状态逻辑复杂时,useReducer 比 useState 更适合:
import { useReducer } from 'react'
const initialState = { count: 0 }
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 }
case 'decrement':
return { count: state.count - 1 }
default:
throw new Error()
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState)
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'increment'})}>+</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
</>
)
}
自定义 Hook
自定义 Hook 是复用逻辑的最佳方式:
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key)
return item ? JSON.parse(item) : initialValue
} catch (error) {
return initialValue
}
})
const setValue = (value) => {
setStoredValue(value)
window.localStorage.setItem(key, JSON.stringify(value))
}
return [storedValue, setValue]
}
// 使用
const [theme, setTheme] = useLocalStorage('theme', 'light')
Hooks 使用规则
- 只在函数组件或自定义 Hook 中调用 Hooks
- 只在最顶层调用 Hooks,不要在循环、条件或嵌套函数中调用
- 自定义 Hook 的名称必须以 use 开头
总结
React Hooks 极大地简化了 React 开发,让代码更易读、更易测试。掌握 Hooks 是成为优秀 React 开发者的必经之路。