You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将Ref向下传递给子组件?子组件如何获取父组件的Ref以获取其宽度?

React Ref 相关问题解答

1. 如何将一个 ref 向下转发到子组件?

这正是 forwardRef 方法的核心用途!它能让父组件把自己创建的 ref 传递给子组件内部的 DOM 元素或组件实例,步骤很清晰:

  • 首先用 React.forwardRef() 包裹子组件,这样子组件就能接收额外的 ref 参数(第二个参数,第一个是常规 props)。
  • 然后把这个 ref 绑定到子组件内部你需要访问的 DOM 节点或者类组件实例上。

举个直观的例子:

子组件(用 forwardRef 包裹)

const ChildComponent = React.forwardRef((props, ref) => {
  // 将父组件传递的 ref 绑定到内部的 input 元素
  return <input ref={ref} type="text" placeholder="试试点击下方按钮聚焦我" />;
});

父组件(传递 ref 并操作子组件元素)

function ParentComponent() {
  const inputRef = useRef(null);

  const focusInput = () => {
    inputRef.current?.focus(); // 直接操作子组件里的 input 元素
  };

  return (
    <div>
      <ChildComponent ref={inputRef} />
      <button onClick={focusInput}>聚焦输入框</button>
    </div>
  );
}

这样父组件就能通过自己创建的 inputRef 直接控制子组件内部的 DOM 元素了。

2. 如何把父组件的 ref 传递给子组件,让子组件获取父组件的宽度?

这个场景和 forwardRef 的方向正好相反——不是子组件暴露自己的 ref 给父组件,而是父组件把自己的 ref 传给子组件。其实不用复杂的 API,直接把父组件的 ref 作为普通 props 传给子组件就行

具体操作步骤:

  1. 父组件创建自己的 ref,绑定到自身的容器元素上。
  2. 把这个 ref 作为 props 传递给子组件。
  3. 子组件里通过 useEffect 监听,当 ref 绑定到真实 DOM 后获取父组件的宽度,还可以监听窗口 resize 事件来实时更新宽度。

看代码示例:

父组件

function ParentComponent() {
  const parentRef = useRef(null);

  return (
    <div 
      ref={parentRef} 
      style={{ width: "70%", border: "1px solid #eee", padding: "1rem", margin: "0 auto" }}
    >
      <ChildComponent parentRef={parentRef} />
    </div>
  );
}

子组件

function ChildComponent({ parentRef }) {
  const [parentWidth, setParentWidth] = useState(0);

  useEffect(() => {
    // 定义获取父组件宽度的函数
    const updateParentWidth = () => {
      if (parentRef.current) {
        setParentWidth(parentRef.current.offsetWidth);
      }
    };

    // 组件挂载后初始化获取宽度
    updateParentWidth();

    // 监听窗口 resize,宽度变化时更新
    window.addEventListener("resize", updateParentWidth);

    // 组件卸载时清理监听事件
    return () => {
      window.removeEventListener("resize", updateParentWidth);
    };
  }, [parentRef]);

  return <p>父组件当前宽度:{parentWidth}px</p>;
}

这里要注意:必须在 useEffect 里处理,因为组件挂载后 ref 才会绑定到真实 DOM,直接在渲染阶段访问 parentRef.current 大概率会拿到 null。加上 resize 监听,能保证父组件宽度变化时子组件能实时同步数据。


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

火山引擎 最新活动