# 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(setUser);
}, [userId]);
const windowWidth = useWindowWidth();
if (!user) return <Loader />;
return (
<div style={{ width: windowWidth > 500 ? '50%' : '100%' }}>
<h1>{user.name}</h1>
<p>{user.bio}</p>
</div>
);
}
3. 性能优化更精细
- 传统方案:shouldComponentUpdate需要手动实现
- Hooks方案:useMemo/useCallback精细控制
const ExpensiveComponent = React.memo(({ data, onClick }) => {
const result = useMemo(() => {
return heavyComputation(data);
}, [data]);
return <div onClick={onClick}>{result}</div>;
});
function Parent() {
const [data, setData] = useState([]);
const handleClick = useCallback(() => {
console.log('Clicked');
}, []);
return <ExpensiveComponent data={data} onClick={handleClick} />;
}
主要使用场景
1. 状态管理
- useState: 基础状态管理
- useReducer: 复杂状态逻辑
function Counter() {
const [count, dispatch] = useReducer((state, action) => {
switch (action.type) {
case 'increment': return state + 1;
case 'decrement': return state - 1;
default: return state;
}
}, 0);
return (
<>
Count: {count}
<button onClick={() => dispatch({type: 'increment'})}>+</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
</>
);
}
2. 副作用处理
- useEffect: 数据获取、订阅等
- 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. 上下文访问
const ThemeContext = React.createContext('light');
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={theme}>按钮</button>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedButton />
</ThemeContext.Provider>
);
}
4. 引用操作
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick