如何设计一个 React 自定义 Hook?

探讨 React Hooks 的使用规则与自定义 Hook 的设计方法。

React 中等 Hooks State Management

1. React Hooks 使用规则
根据官方规范,必须遵循以下核心原则:

  1. 只在顶层调用
    • 不可在循环、条件或嵌套函数中调用 Hooks(如 if (x) useState()),必须无条件地置于函数组件顶部,确保每次渲染时 Hook 顺序相同。
  2. 仅在函数组件或自定义 Hook 中使用
    • 禁止在普通 JavaScript 函数或类组件中调用 Hooks。

2. 自定义 Hook 设计方法

  1. 命名规则:函数名以 use 开头(如 useWindowSize),便于 React 识别其为 Hook。
  2. 内部逻辑组合:可自由组合内置 Hooks(如 useStateuseEffect)实现逻辑复用,例如:
    // 示例:提取窗口尺寸获取逻辑
    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; // 返回状态数据
    }
    
  3. 独立状态隔离
    • 自定义 Hook 多次调用时各组件状态相互隔离(类似函数局部作用域),避免了高阶组件的嵌套问题。
  4. 目的:替代高阶组件或 Render Props,实现无嵌套的跨组件逻辑复用(如数据获取、事件监听等)。

遵循规则能规避 Hook 调用顺序混乱导致的 Bug,而自定义 Hook 通过解耦逻辑显著提升代码可维护性。