React Hooks 入门:常用 API 与使用注意

React Hooks 入门:常用 API 与使用注意

Hooks 让你在函数组件里使用 state、副作用、上下文等能力,而无需写 class。React 16.8 起稳定支持。使用 Hooks 时需遵守 Hooks 规则(只在顶层调用、只在 React 函数里调用)。

基础 Hooks

useState

为组件增加本地状态

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);
  return (
    <button type="button" onClick={() => setCount((c) => c + 1)}>
      {count}
    </button>
  );
}
  • 初始值可以是任意类型;若初始状态计算较贵,可传入 useState(() => expensive())(惰性初始化)。
  • 不要直接修改 state 对象/数组,应拷贝后再 setState

useEffect

处理副作用:请求数据、订阅、操作 DOM、定时器等。

import { useEffect, useState } from "react";

function Profile({ userId }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    let cancelled = false;
    async function load() {
      const res = await fetch(`/api/user/${userId}`);
      const json = await res.json();
      if (!cancelled) setData(json);
    }
    load();
    return () => {
      cancelled = true;
    };
  }, [userId]);

  return data ? <p>{data.name}</p> : <p>加载中…</p>;
}
  • 依赖数组[] 表示仅挂载/卸载时执行一次;[userId]userId 变化时重新执行。
  • 清理函数 return () => {}:取消订阅、清除定时器、忽略过期请求结果等。

useContext

消费 React.createContext 提供的值,避免层层传递 props。

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

function Button() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>OK</button>;
}

额外 Hooks(常用)

useReducer

适合状态逻辑复杂、多子值或依赖上一状态更新的场景,可视为 useState 的强化版。

const [state, dispatch] = useReducer(reducer, initialState);

useMemo

缓存计算结果,依赖不变则复用上次值,减轻子组件重复计算(注意:不是万能性能药)。

const sorted = useMemo(() => items.slice().sort(compare), [items]);

useCallback

缓存函数引用,常与子组件 React.memo 配合,避免无关重渲染。

const onSave = useCallback(() => {
  save(id);
}, [id]);

useRef

保存可变引用不触发重渲染:DOM 节点、定时器 id、任意可变盒。

const inputRef = useRef(null);
useEffect(() => {
  inputRef.current?.focus();
}, []);

useLayoutEffect

在浏览器绘制之后、用户看到之前同步执行,适合测量 DOM、避免闪烁;大部分场景用 useEffect 即可。

自定义 Hook

把可复用的状态逻辑抽成 useXxx 函数,内部可调用其他 Hooks。

function useWindowWidth() {
  const [w, setW] = useState(() => window.innerWidth);
  useEffect(() => {
    const onResize = () => setW(window.innerWidth);
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, []);
  return w;
}

Hooks 使用规则(摘要)

  1. 只在函数组件顶层自定义 Hook 里调用 Hooks,不要在循环、条件或嵌套函数里调用。
  2. 自定义 Hook 以 use 开头,便于 ESLint 插件 eslint-plugin-react-hooks 检查。

小结

Hook典型用途
useState组件内状态
useEffect副作用与清理
useContext跨层数据
useReducer复杂状态转移
useMemo / useCallback按需稳定引用、减少无效计算
useRefDOM 与可变值

新代码建议以函数组件 + Hooks为主;类组件仍可在维护旧项目时遇到。官方文档:React Hooks 概览open in new window

Last Updated 4/9/2026, 6:16:02 AM