You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useRef与forwardRef结合使用的正确方法及TS报错解决

错误原因

  1. 你没有为React.forwardRef指定泛型参数,TS默认推导转发的ref类型为unknown,和你内部声明的HTMLDivElement类型ref不匹配,这是类型报错的直接诱因。
  2. 转发的ref存在两种合法形式:RefObject对象、回调函数,你直接用ref || innerRef的写法只兼容了对象形式的ref,没有覆盖回调ref的场景,逻辑本身存在缺陷。

修复方案

你可以通过回调ref的形式同时为内部ref和转发ref赋值,完全覆盖所有场景,也不会有类型问题:

  1. 首先修改App.tsx,给内部ref指定正确的类型:
import { useRef } from "react";
import Child from "./Child";

export default function App() {
  // 明确ref指向的是HTMLDivElement类型
  const ref = useRef<HTMLDivElement>(null);
  console.log("App ref: ", ref);
  return (
    <div className="App">
      <Child ref={ref} />
    </div>
  );
}
  1. 再修改Child.tsx,补全forwardRef泛型,用回调ref同步两个ref的值:
import React, { useEffect, useRef } from "react";

// 第一个泛型指定ref暴露的类型为HTMLDivElement,第二个泛型指定组件props类型
export default React.forwardRef<HTMLDivElement, Record<string, never>>((props, ref) => {
  const innerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    // 内部直接使用innerRef即可
    if (innerRef.current) {
      console.log("clientWidth: ", innerRef.current.clientWidth);
      // 执行你需要的DOM操作
    }
  }, []);

  return (
    <div
      ref={(node) => {
        // 同步DOM节点到内部ref
        innerRef.current = node;
        // 同步DOM节点到父组件转发的ref
        if (typeof ref === "function") {
          ref(node);
        } else if (ref) {
          ref.current = node;
        }
      }}
    ></div>
  );
});

方案说明

  • 所有类型完全匹配,不会再触发TS报错
  • 同时兼容了对象形式、回调形式的转发ref,覆盖所有合法使用场景
  • 内部逻辑直接使用innerRef即可,不需要额外处理转发ref的类型差异
  • 父组件可以正常拿到子组件内部的div DOM元素,符合预期功能

内容的提问来源于stack exchange,提问作者Lin Du

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 09:57:03