React Hooks 的优势和使用场景

34 阅读1分钟
# 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. 上下文访问

  • useContext: 跨组件数据共享
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. 引用操作

  • useRef: DOM引用/保持可变值
function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  
  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick