# React Hooks 的优势和使用场景
## 核心优势
### 1. 逻辑复用更简单
- 传统方案:高阶组件(HOC)或render props会导致"嵌套地狱"
- Hooks方案:自定义Hook可提取状态逻辑,实现干净复用
```jsx
// 自定义Hook示例
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
// 在组件中使用
function MyComponent() {
const width = useWindowWidth();
return <div>窗口宽度: {width}px</div>;
}
2. 代码组织更清晰
- 传统class组件:相关逻辑分散在不同生命周期
- Hooks方案:按功能组织代码,相关逻辑集中处理
function UserProfile({ userId }) {
// 用户数据相关
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then(data => setUser(data));
}, [userId]);
// 主题偏好相关
const [theme, setTheme] = useLocalStorage('theme', 'light');
// 渲染逻辑
if (!user) return <Loader />;
return (
<div className={theme}>
<Avatar user={user} />
<ProfileDetails user={user} />
</div>
);
}
3. 减少组件复杂度
- 无需处理this绑定问题
- 函数组件更轻量,性能更好
- 更易于理解和测试
主要使用场景
1. 状态管理
useState: 基础状态管理useReducer: 复杂状态逻辑
function Counter() {
const [count, setCount] = useState(0);
const increment = () => setCount(c => c + 1);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
</div>
);
}
2. 副作用处理
useEffect: 数据获取、订阅、手动DOM操作useLayoutEffect: DOM变更后同步执行
function DataFetcher({ url }) {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
let isMounted = true;
fetch(url)
.then(res => res.json())
.then(data => isMounted && setData(data))
.catch(err => isMounted && setError(err));
return () => { isMounted = false };
}, [url]);
if (error) return <ErrorDisplay error={error} />;
if (!data) return <Loader />;
return <DataDisplay data={data} />;
}
3. 性能优化
useMemo: 缓存计算结果useCallback: 缓存函数引用
function ExpensiveComponent({ items, filter }) {
const filteredItems = useMemo(() => {
return items.filter(item => item.includes(filter));
}, [items, filter]);
return <List items={filteredItems} />;
}
4. 访问DOM/Ref
useRef: 获取DOM引用或保存可变值
function TextInputWithFocus() {
const inputEl = useRef(null);
const focusInput = () => {
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={focusInput}>Focus</button>
</>
);
}
5. 上下文访问
useContext: 无需嵌套消费Context
const ThemeContext = createContext('light');
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme === 'dark' ? '#333' : '#fff' }}>
Themed Button
</button>
);
}
最佳实践
-
遵循Hook调用规则
- 只在React函数组件或自定义Hook中调用
- 不要在循环、条件或嵌套函数中调用
-
合理拆分自定义Hook
- 每个Hook应该只关注一个特定功能
- 命名