如何在 React 中正确地使用 useRef 来访问子组件的 DOM 元素或实例?

如何在 React 中正确地使用 useRef 来访问子组件的 DOM 元素或实例?

回答:
在 React 中,若要通过 useRef 访问子组件的 DOM 元素或实例,需配合 forwardRef 和 useImperativeHandle(如需暴露自定义方法)一起使用。

示例代码:

// 子组件
import { forwardRef, useImperativeHandle, useRef } from 'react';

const Child = forwardRef((props, ref) => {
  const inputRef = useRef(null);

  // 暴露自定义方法或 DOM 节点给父组件
  useImperativeHandle(ref, () => ({
    focus: () => inputRef.current.focus(),
    // 或直接暴露 inputRef.current(不推荐直接暴露 DOM,除非必要)
  }));

  return <input ref={inputRef} />;
});

// 父组件
const Parent = () => {
  const childRef = useRef();

  const handleClick = () => {
    childRef.current.focus(); // 调用子组件暴露的方法
  };

  return (
    <>
      <Child ref={childRef} />
      <button onClick={handleClick}>Focus Input</button>
    </>
  );
};

解析:

  • 默认情况下,React 的 ref 无法直接绑定到函数组件上(因为函数组件没有实例)。
  • 使用 React.forwardRef 可将 ref 转发到内部 DOM 节点或通过 useImperativeHandle 暴露特定 API。
  • useImperativeHandle 允许你自定义暴露给父组件的 ref 对象,避免直接暴露整个 DOM 节点,提高封装性和安全性。
  • 此模式常用于表单控件、动画组件或需要命令式调用的场景(如手动聚焦、播放视频等)。

注意:应尽量避免过度使用 ref 进行命令式操作,优先考虑通过 props 和状态进行声明式控制。

发表评论 (审核通过后显示评论):

昵称:
邮箱:
内容: