React Hooks 的优势和使用场景

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

## 1. 代码复用性提升
- **自定义Hook封装逻辑**:可将组件逻辑提取到可重用的函数中
```javascript
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, height } = useWindowSize();
  • 替代HOC和Render Props:避免组件嵌套地狱
// 替代前(HOC方式)
withRouter(connect(MyComponent))

// 替代后(Hook方式)
const router = useRouter()
const store = useStore()

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]);

  // UI渲染
  return isOnline ? 'Online' : 'Offline';
}

3. 性能优化更精细

  • 条件式effect:依赖项数组控制执行时机
useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // 仅在count变化时更新
  • 记忆化计算:useMemo避免重复计算
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

4. 生命周期简化

  • useEffect统一处理:替代三个生命周期方法
// 替代componentDidMount
useEffect(() => {
  // 初始化逻辑
}, []);

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

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

5. 状态管理更灵活

  • useReducer处理复杂状态:类似Redux的reducer模式
function todosReducer(state, action) {
  switch (action.type) {
    case 'add':
      return [...state, action.payload];
    default:
      return state;
  }
}

function Todos() {
  const [todos, dispatch] = useReducer(todosReducer, []);
  // 使用dispatch({ type: 'add', payload: newTodo })
}

6. 使用场景指南

  1. 表单处理:useState + useEffect
function Form() {
  const [values, setValues] = useState({});
  const handleChange = (e) => {
    setValues({
      ...values,
      [e.target.name]: e.target.value
    });
  };
  // 表单验证可使用useEffect监听values变化
}
  1. 数据获取:useEffect + useState
function useFetch(url) {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(setData);
  }, [url]);
  return data;
}
  1. 动画效果:useRef + useEffect
function FadeIn({ children }) {
  const ref = useRef(null);
  useEffect(() => {
    const node = ref.current;
    node.style.transition = 'opacity 1s';
    node.style.opacity = 1;
  }, []);
  return <div ref={ref} style={{opacity: 0}}>{children}</div>;
}
  1. 全局状态共享: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' }}>
}

7. 注意事项