React Hooks 的优势和使用场景

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

## 1. React Hooks 的优势

### 1.1 简化组件逻辑
Hooks 允许在不编写 class 的情况下使用 state 和其他 React 特性。通过将组件拆分为更小的函数,而不是强制基于生命周期方法进行拆分,使代码更易于理解和维护。

```jsx
// 使用 useState 管理状态
function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

1.2 复用状态逻辑

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

// 自定义 Hook 复用逻辑
function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    
    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  }, [friendID]);

  return isOnline;
}

1.3 减少代码量

相比 class 组件,函数组件配合 Hooks 通常需要更少的代码量,同时保持了相同的功能。

// Class 组件 vs 函数组件+Hooks
// Class 版本
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

// Hooks 版本
function Example() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

1.4 更好的性能优化

Hooks 如 useMemo 和 useCallback 提供了细粒度的性能优化手段,可以避免不必要的渲染和计算。

function MyComponent({ list }) {
  const memoizedValue = useMemo(() => computeExpensiveValue(list), [list]);
  
  const handleClick = useCallback(() => {
    console.log('Clicked!');
  }, []);
  
  return <ExpensiveComponent value={memoizedValue} onClick={handleClick} />;
}

2. React Hooks 的使用场景

2.1 状态管理

useState 是最基础的 Hook,适用于管理组件内部的状态。

function Form() {
  const [name, setName] = useState('Mary');
  const [age, setAge] = useState(25);

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

2.2 副作用处理

useEffect 用于处理副作用,如数据获取、订阅、手动修改 DOM 等。

function DataFetcher({ id }) {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    let ignore = false;
    
    async function fetchData() {
      const response = await fetch(`/api/data/${id}`);
      const result = await response.json();
      if (!ignore) setData(result);
    }
    
    fetchData();
    return () => { ignore = true; };
  }, [id]);

  return <div>{data ? data.name : 'Loading...'}</div>;
}

2.3 上下文访问

useContext 可以方便地访问 React 的 Context,避免了传统的 Consumer 组件嵌套。

const ThemeContext = React.createContext('light');

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>I am styled by theme context!</button>;
}

2.4 复杂状态逻辑

useReducer 适用于管理包含多个子值的复杂 state 逻辑。

function todosReducer(state, action) {
  switch (