一、React Hooks 的理解
简单来说:
Hooks = 在函数组件中“钩入(Hook)”React状态和生命周期的函数。
它解决了几个问题:
1 让函数组件也能有状态
以前函数组件只能展示 UI,没有状态。
function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
)
}
2 替代复杂的生命周期
类组件生命周期:
componentDidMount
componentDidUpdate
componentWillUnmount
Hooks 用 useEffect 统一管理。
3 逻辑复用更简单
以前复用逻辑需要:
- HOC(高阶组件)
- Render Props
Hooks 可以直接抽成函数:
function useUser() {
const [user, setUser] = useState(null)
}
二、常用 React Hooks
开发中最常用的大概 7 个。
1 useState(最常用)
用于 管理组件状态。
import { useState } from "react"
function Demo() {
const [count, setCount] = useState(0)
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
)
}
特点:
useState(初始值)- 返回
[state, setState] - setState 会触发组件重新渲染
2 useEffect(生命周期)
用于 处理副作用:
- 请求接口
- 操作 DOM
- 订阅事件
- 定时器
import { useEffect } from "react"
useEffect(() => {
console.log("组件加载")
return () => {
console.log("组件卸载")
}
}, [])
依赖数组控制执行:
| 写法 | 含义 |
|---|---|
| useEffect(fn) | 每次渲染执行 |
| useEffect(fn, []) | 只执行一次 |
| useEffect(fn, [a]) | a变化执行 |
3 useRef
用于:
1️⃣ 获取 DOM
2️⃣ 保存变量(不触发渲染)
const inputRef = useRef(null)
<input ref={inputRef} />
inputRef.current.focus()
4 useContext
用于 跨组件传值(避免 props 逐层传递)。
const ThemeContext = createContext()
function App() {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
)
}
function Child() {
const theme = useContext(ThemeContext)
}
5 useMemo(性能优化)
缓存计算结果
防止重复计算。
const result = useMemo(() => {
return expensiveFunction(a, b)
}, [a, b])
只有 a b 变化才重新计算。
6 useCallback
缓存函数
防止子组件重复渲染。
const handleClick = useCallback(() => {
console.log("click")
}, [])
常配合 React.memo 使用。
7 useReducer
用于 复杂状态管理(类似 Redux)。
const [state, dispatch] = useReducer(reducer, initialState)
dispatch({ type: "add" })
适合:
- 多状态
- 状态依赖复杂
三、Hooks 使用规则(面试必问)
React Hooks 必须遵守两个规则:
1 只能在函数组件或自定义 Hook 中使用
❌ 错误
if (a) {
useState()
}
2 必须在组件顶层调用
不能在:
- if
- for
- function
里面调用。
四、自定义 Hook(高级)
可以封装逻辑。
例如封装请求:
function useFetch(url) {
const [data, setData] = useState(null)
useEffect(() => {
fetch(url).then(res => res.json()).then(setData)
}, [url])
return data
}
使用:
const data = useFetch("/api/user")
五、React Hooks 优势总结
| 优势 | 说明 |
|---|---|
| 代码更简洁 | 不需要 class |
| 逻辑复用 | 自定义 Hook |
| 生命周期更清晰 | useEffect |
| 减少嵌套 | 不需要 HOC |