React Hooks 的优势和使用场景

25 阅读2分钟
# React Hooks 的优势和使用场景

## 1. 代码复用性提升
- **自定义Hook封装逻辑**:可将组件逻辑提取到可重用的函数中
```jsx
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;
}
// 在任何组件中调用
const { width } = useWindowSize();
  • 替代HOC和Render Props:避免组件嵌套地狱
// 替代前(HOC方式)
withTracker(MyComponent)
// 替代后(Hook方式)
const data = useTracker();

2. 逻辑关注点分离

  • 按功能组织代码:相关代码可以集中在一起
function FriendStatus({ friendId }) {
  // 状态逻辑集中
  const [isOnline, setIsOnline] = useState(null);
  
  // 副作用逻辑集中
  useEffect(() => {
    const handleStatusChange = status => setIsOnline(status.isOnline);
    ChatAPI.subscribe(friendId, handleStatusChange);
    return () => ChatAPI.unsubscribe(friendId, handleStatusChange);
  }, [friendId]);

  return isOnline ? 'Online' : 'Offline';
}

3. 性能优化更精细

  • 条件式effect:通过依赖数组控制更新
useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // 仅在count变化时更新
  • useMemo/useCallback:避免不必要的计算和渲染
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);

4. 类组件痛点解决

  • 消除this绑定问题:函数组件无需处理this
  • 简化生命周期:useEffect统一处理副作用
// 替代componentDidMount
useEffect(() => {
  // 挂载逻辑
}, []);

// 替代componentDidUpdate
useEffect(() => {
  // 更新逻辑
});

// 替代componentWillUnmount
useEffect(() => {
  return () => {
    // 清理逻辑
  };
}, []);

5. 状态管理更灵活

  • useReducer:复杂状态逻辑处理
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, {count: 0});
  return (
    <button onClick={() => dispatch({type: 'increment'})}>
      {state.count}
    </button>
  );
}
  • useContext:跨组件共享状态
const ThemeContext = createContext('light');

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div>{theme}</div>;
}

6. 特殊场景解决方案

  • useRef:访问DOM/保存可变值
function TextInput() {
  const inputEl = useRef(null);
  const onButtonClick = () => inputEl.current.focus();
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus</button>
    </>
  );
}
  • useLayoutEffect:同步DOM变更
useLayoutEffect(() => {
  // 在浏览器绘制前执行DOM测量
  const height = ref.current.clientHeight;
  // 使用测量结果...
});

7. 渐进式迁移策略

  • 与类组件共存:项目可逐步迁移
  • 无破坏性变更:现有代码继续有效

8. 未来发展趋势

  • 函数式编程导向:更符合React理念
  • 并发模式准备:Hooks设计兼容未来特性
  • 官方推荐实践:新文档和