React Hooks 的优势和使用场景

44 阅读1分钟
# React Hooks 的优势和使用场景

## 1. 代码复用性提升
- **自定义Hook封装逻辑**:可将组件逻辑提取到可重用的函数中
```jsx
// 自定义计数器Hook
function useCounter(initialValue) {
  const [count, setCount] = useState(initialValue);
  const increment = () => setCount(c => c + 1);
  return [count, increment];
}

// 组件中使用
function ComponentA() {
  const [count, increment] = useCounter(0);
  return <button onClick={increment}>{count}</button>;
}
  • 替代HOC和Render Props:减少组件嵌套层级
// 替代高阶组件
function useUser() {
  const [user, setUser] = useState(null);
  useEffect(() => {
    fetchUser().then(setUser);
  }, []);
  return user;
}

// 直接使用
function Profile() {
  const user = useUser();
  return <div>{user?.name}</div>;
}

2. 逻辑关注点分离

  • 按功能组织代码:相关逻辑可以集中在一起
function FriendStatus({ friendId }) {
  // 状态逻辑
  const [isOnline, setIsOnline] = useState(null);

  // 副作用逻辑
  useEffect(() => {
    const handleStatusChange = status => setIsOnline(status.isOnline);
    subscribeToFriendStatus(friendId, handleStatusChange);
    return () => unsubscribeFromFriendStatus(friendId, handleStatusChange);
  }, [friendId]);

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

3. 性能优化更精细

  • memoization优化:useMemo/useCallback减少不必要的计算
function ExpensiveComponent({ list }) {
  const sortedList = useMemo(
    () => list.sort((a, b) => a.value - b.value),
    [list]
  );

  const handleClick = useCallback(() => {
    console.log('Item clicked');
  }, []);

  return <List items={sortedList} onClick={handleClick} />;
}
  • 精准控制更新:依赖项数组精确控制effect执行时机
useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // 仅在count变化时更新

4. 简化生命周期管理

  • useEffect统一处理:替代componentDidMount/Update/Unmount
useEffect(() => {
  // componentDidMount + componentDidUpdate
  const handler = () => console.log('resized');
  window.addEventListener('resize', handler);
  
  // componentWillUnmount
  return () => window.removeEventListener('resize', handler);
}, []);
  • 多个effect分离关注点
// 网络请求
useEffect(() => {
  fetchData(id);
}, [id]);

// DOM操作
useEffect(() => {
  document.title = title;
}, [title]);

5. 典型使用场景

表单处理

function Form() {
  const [values, setValues] = useState({});
  const handleChange = useCallback((e) => {
    setValues(v => ({...v, [e.target.name]: e.target.value}));
  }, []);

  return (
    <form>
      <input name="username" onChange={handleChange} />
      <input name="password" onChange={handleChange} />
    </form>
  );
}

全局状态管理

// 创建Context
const UserContext = createContext();

function App() {
  const [user, setUser] = useState(null);
  return (
    <UserContext.Provider value={{ user, setUser }}>
      <ChildComponent />
    </UserContext.Provider>
  );
}

// 使用Context
function ChildComponent() {
  const { user } = useContext(UserContext);
  return <div>{user?.name}</div>;
}

动画效果

function BouncingBall() {
  const [position, setPosition] = useState(0);
  const direction = useRef(1);

  useAnimationFrame(() => {
    setPosition(p => {
      if (p > 100) direction.current = -1;
      if (p < 0) direction.current = 1;
      return p + direction.current;
    });
  });

  return <div style={{ transform: `translateY(${position}px)` }} />;
}

6. 注意事项

  1. 只在顶层调用Hook:不要在