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

React+TypeScript:如何在子组件中使用forwardRef传递的引用数据

问题解答

1. 先明确:用forwardRef传递非DOM/组件实例的数据,并不推荐

React官方虽然提到useRef可以存储不触发渲染的数据,但forwardRef的设计初衷是传递DOM元素或自定义组件的引用,而非普通数据。用它来传数据会违背React的语义,还会带来类型处理的麻烦(比如你遇到的Ref<T>包含函数式ref和对象式ref的混合类型问题),属于非常规用法,不建议这么做。

2. 更合适的替代方案:用普通props传递ref对象

直接把useRef创建的对象作为普通props传给子组件,类型清晰,也符合React的常规用法:

import { useRef } from 'react';

function ParentComponent() {
  const someData = useRef(1);
  // 改变someData.current的逻辑
  return <ChildComponent dataRef={someData} />;
}

interface ChildProps {
  dataRef: React.MutableRefObject<number>;
}

function ChildComponent({ dataRef }: ChildProps) {
  const onClick = () => {
    // 直接访问current,类型完全明确
    console.log(dataRef.current);
  };

  return <button onClick={onClick} type="button">点击</button>;
}

这种方式下,子组件可以随时拿到dataRef.current的最新值,而且不需要处理混合类型的ref,类型安全无歧义。

3. 如果非要用forwardRef,怎么处理类型问题

如果你坚持要用forwardRef传递数据,需要先区分ref的类型(函数式ref还是对象式ref),因为函数式ref是用来接收实例的回调,根本不适合存储数据,所以我们只处理对象式ref的情况:

import { forwardRef, useRef } from 'react';

function ParentComponent() {
  const someData = useRef(1);
  return <ChildComponent ref={someData} />;
}

const ChildComponent = forwardRef<number>((props, ref) => {
  const onClick = () => {
    // 先判断ref是否为对象式ref
    if (ref && 'current' in ref) {
      const currentValue = ref.current;
      console.log(currentValue); // 类型为number | null
    }
  };

  return <button onClick={onClick} type="button">点击</button>;
});

如果你能100%确定父组件传递的是对象式ref(比如自己维护的代码),也可以强制类型转换,但要注意风险(如果后续改成函数式ref会报错):

const onClick = () => {
  const refObj = ref as React.MutableRefObject<number | null>;
  console.log(refObj.current);
};

总结

  • 优先选择普通props传递ref对象的方案,类型安全、符合React设计语义;
  • 尽量避免用forwardRef传递普通数据,否则会引入不必要的类型复杂度;
  • 若必须用forwardRef,优先通过类型判断处理对象式ref,而非直接强制转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:23:00