React Hooks 的优势和使用场景

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

## 1. React Hooks 的核心优势

### 1.1 简化组件逻辑
Hooks 允许在不编写 class 的情况下使用 state 和其他 React 特性。通过 `useState` 可以轻松管理组件状态:

```jsx
function Counter() {
  const [count, setCount] = useState(0); // 一行代码替代整个class结构

  return (
    <button onClick={() => setCount(count + 1)}>
      Clicked {count} times
    </button>
  );
}

1.2 逻辑复用能力

自定义 Hook 可以提取组件逻辑到可重用函数中,解决了高阶组件和render props带来的"嵌套地狱"问题:

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();
  // ...
}

1.3 更好的代码组织

相关逻辑可以集中在一起,而不是分散在不同的生命周期方法中:

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]); // 仅在friendId变化时重新订阅

  // ...
}

2. 主要Hooks的使用场景

2.1 useState - 状态管理

适用于:

  • 组件本地状态管理
  • 表单控件状态
  • 简单的UI状态切换
function Form() {
  const [name, setName] = useState('');
  const [age, setAge] = useState(18);

  return (
    <>
      <input value={name} onChange={e => setName(e.target.value)} />
      <input 
        type="number" 
        value={age} 
        onChange={e => setAge(Number(e.target.value))}
      />
    </>
  );
}

2.2 useEffect - 副作用处理

典型使用场景:

  • 数据获取
  • 事件订阅
  • DOM操作
  • 定时器管理
function DataFetcher({ url }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    let ignore = false;
    
    async function fetchData() {
      const response = await fetch(url);
      const result = await response.json();
      if (!ignore) setData(result);
    }

    fetchData();
    
    return () => { ignore = true; }; // 清理函数避免竞态条件
  }, [url]); // url变化时重新获取

  return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
}

2.3 useContext - 跨组件共享状态

适合:

  • 主题切换
  • 用户认证信息
  • 全局配置
const ThemeContext = createContext('light');

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

function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div style={{ background: theme === 'dark' ? '#333' : '#FFF' }} />;
}

2.4 useReducer - 复杂状态逻辑

适用场景:

  • 具有多个子值的state
  • 下一个state依赖前一个state
  • 复杂的业务逻辑
function todosReducer(state, action) {
  switch (action.type) {
    case 'add':
      return [...state, { text: action.text, completed: false }];
    case 'toggle':
      return state.map((todo, i) => 
        i === action.index ? {...todo, completed: !todo.completed} : todo
      );
    default:
      return state;
  }
}

function TodoList() {
  const [todos, dispatch] = useReducer(todosReducer, []);

  return (
    <>
      {todos.map((todo, i) => (
        <div key={i} onClick={() => dispatch({ type: 'toggle', index: i })}>
          {todo.text}