React Hooks 的优势和使用场景

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

## 核心优势

### 1. 逻辑复用更简单
- 解决了高阶组件(HOC)的嵌套地狱问题
- 避免了render props的模式冗余
- 自定义Hook可以提取组件逻辑到可重用函数

```jsx
// 自定义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;
}

// 在组件中使用
function MyComponent() {
  const { width } = useWindowSize();
  return <div>Window width: {width}px</div>;
}

2. 代码组织更清晰

  • 相关逻辑可以集中在一起
  • 不再需要拆分生命周期方法
  • 状态逻辑与UI呈现分离
function UserProfile({ userId }) {
  // 状态管理集中
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  // 数据获取逻辑集中
  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      try {
        const response = await fetch(`/api/users/${userId}`);
        setUser(await response.json());
      } catch (err) {
        setError(err);
      } finally {
        setLoading(false);
      }
    };
    
    fetchData();
  }, [userId]);

  // UI渲染
  if (loading) return <Spinner />;
  if (error) return <Error message={error.message} />;
  return <Profile user={user} />;
}

3. 学习成本更低

  • 不需要理解class组件中的this绑定
  • 不需要记忆生命周期方法
  • 更接近纯函数编程思想

主要使用场景

1. 状态管理

  • useState: 基础状态管理
  • useReducer: 复杂状态逻辑
  • useContext: 跨组件状态共享
// 状态管理示例
function Counter() {
  const [count, setCount] = useState(0);
  const [step, setStep] = useState(1);

  return (
    <>
      <button onClick={() => setCount(c => c + step)}>
        Increment by {step}
      </button>
      <input 
        type="number" 
        value={step}
        onChange={e => setStep(Number(e.target.value))}
      />
      <div>Current count: {count}</div>
    </>
  );
}

2. 副作用处理

  • useEffect: 数据获取、订阅、手动DOM操作
  • useLayoutEffect: DOM变更后同步执行
  • useInsertionEffect: 样式注入
// 副作用示例
function DataFetcher({ url }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    let isMounted = true;
    
    const fetchData = async () => {
      const response = await fetch(url);
      if (isMounted) setData(await response.json());
    };

    fetchData();
    
    return () => {
      isMounted = false; // 清理函数
    };
  }, [url]);

  return <div>{JSON.stringify(data)}</div>;
}

3. 性能优化

  • useMemo: 记忆计算结果
  • useCallback: 记忆回调函数
  • useTransition: 非阻塞UI更新
// 性能优化示例
function ExpensiveComponent({ items, filter }) {
  const filteredItems = useMemo(() => {
    return items.filter(item => item.includes(filter));
  }, [items, filter]);

  const handleClick = useCallback((item) => {
    console.log('Selected:', item);
  }, []);

  return (
    <ul>
      {filteredItems.map(item => (
        <li key={item} onClick={() => handleClick(item)}>
          {item}
        </li>
      ))}
    </ul>
  );
}

4. 访问DOM元素

  • useRef: 获取DOM引用
  • forwardRef: 转发ref到子组件
// DOM操作示例
function AutoFocusInput() {