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

如何为组件分配ref并传递给子组件?解决ref.current为null问题

问题解决方法

核心问题分析

你直接传ref.current给子组件时,第一次渲染父组件的DOM还未完成挂载,ref.current此时是null——React会在组件挂载完成后的commit阶段才把DOM元素赋值给ref,比渲染阶段晚,所以子组件拿到的target自然为空。

以下是两种可行的解决思路:

思路一:传递ref对象而非ref.current

父组件把整个ref对象传给子组件,子组件在useEffect里监听ref的变化并访问其current属性:

父组件修改:

return (
  <div
    ref={ref}
    onMouseOver={isSelecting ? handleMouseOver : undefined}
    onClick={isSelecting ? handleClick : undefined}
    className='rich-html prose prose-sm dark:prose-invert md:prose-base lg:prose-lg'
  >
    {parse(html, options)}
    <RichHtmlContextMenu targetRef={ref} /> {/* 传递ref对象 */}
  </div>
);

子组件修改:

interface Props {
  targetRef: React.RefObject<HTMLDivElement>;
}

const RichHtmlContextMenu = ({ targetRef }: Props) => {
  useEffect(() => {
    // 先判断DOM是否已挂载,再执行逻辑
    if (targetRef.current) {
      refs.setReference(targetRef.current.firstChild as HTMLElement);
    }
  }, [refs, targetRef]);

  // ...其他组件逻辑
};

思路二:使用forwardRef时处理类型问题

如果必须用forwardRef,注意ForwardedRef<T>的类型可能是RefObject<T>或赋值函数,需要先判断类型再访问current:

interface Props {
  // 子组件所需的其他props
}

const RichHtmlContextMenu = forwardRef<HTMLDivElement, Props>((props, ref) => {
  useEffect(() => {
    let targetElement: HTMLElement | null = null;
    // 区分ref是对象类型还是函数类型
    if (typeof ref === 'object' && ref !== null) {
      targetElement = ref.current?.firstChild as HTMLElement | null;
    }
    if (targetElement) {
      refs.setReference(targetElement);
    }
  }, [refs, ref]);

  // ...其他组件逻辑
});

注意:两种方案都要做好空值判断,避免DOM未挂载时出现报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 10:02:16