React Hooks深度解析
从基础使用到底层原理,全面掌握React Hooks
什么是React Hooks?
React Hooks是React 16.8引入的革命性特性,它允许函数组件拥有状态(state)和生命周期等特性,彻底改变了React开发方式。
注意: Hooks只能在函数组件的顶层调用,不能在循环、条件判断或嵌套函数中使用。
1. useState - 状态管理
useState是最基础也最常用的Hook,用于在函数组件中添加状态。
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>点击次数: {count}</p>
<button onClick={() => setCount(count + 1)}>
点击增加
</button>
</div>
);
}
1.1 函数式更新
当新状态依赖于旧状态时,应使用函数式更新:
setCount(prevCount => prevCount + 1);
2. useEffect - 副作用处理
useEffect用于处理副作用操作,如数据获取、订阅、手动DOM操作等。
useEffect(() => {
// 组件挂载时执行
console.log('组件已挂载');
// 返回清理函数
return () => {
console.log('组件即将卸载');
};
}, []); // 空依赖数组,只在挂载和卸载时执行
2.1 依赖数组
依赖数组控制useEffect的执行时机:
// 每次渲染都执行
useEffect(() => { /* ... */ });
// 只在挂载时执行
useEffect(() => { /* ... */ }, []);
// 当count或name变化时执行
useEffect(() => { /* ... */ }, [count, name]);
3. useContext - 跨组件通信
useContext用于在组件树中传递数据,避免prop drilling。
// 创建Context
const ThemeContext = React.createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return <div>当前主题: {theme}</div>;
}
4. useRef - 引用DOM或可变值
useRef返回一个可变的ref对象,其.current属性被初始化为传入的参数。
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>聚焦输入框</button>
</>
);
}
5. useReducer - 复杂状态管理
useReducer是useState的替代方案,适合处理复杂的状态逻辑。
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>
</>
);
}
6. 自定义Hooks
自定义Hook可以将组件逻辑提取到可重用的函数中。
// 自定义Hook:获取窗口大小
function useWindowSize() {
const [size, setSize] = useState({
width: window.innerWidth,
height: window.innerHeight
});
useEffect(() => {
const handleResize = () => {
setSize({
width: window.innerWidth,
height: window.innerHeight
});
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return size;
}
// 使用自定义Hook
function MyComponent() {
const size = useWindowSize();
return <div>窗口大小: {size.width}x{size.height}</div>;
}
7. Hooks最佳实践
7.1 命名约定
- 自定义Hook应以"use"开头
- 状态变量使用描述性名称
- Setter函数以"set"开头
7.2 性能优化
// 使用useMemo缓存计算结果
const memoizedValue = useMemo(() =>
computeExpensiveValue(a, b),
[a, b]
);
// 使用useCallback缓存函数
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b]
);
总结
React Hooks代表了React开发的未来方向,它让代码更加简洁、可重用和易于测试。掌握Hooks不仅能提高开发效率,还能写出更高质量的React代码。
记住以下几点:
- 只在React函数组件中使用Hooks
- 在组件顶层调用Hooks
- 正确处理依赖数组
- 合理使用性能优化Hooks