如何使用 React 中的 forwardRef

React 中父组件通过 ref 属性可以操作子组件中暴露的实际 DOM 元素或者暴露的自定义函数。实现父组件操作子组件这一功能,需要子组件经过 forwardRef 这个 API 包裹才能支持。

本文介绍如何使用 forwardRef 这一 API 实现父组件获取和操作子组件。

获取和操作子组件中的实际 DOM 元素

子组件中用 forwardRef 包裹函数组件。并且将第二个参数 ref 传给实际 DOM 元素。

MyInput.js

jsx 复制代码
import { forwardRef } from 'react';

const MyInput = forwardRef(function MyInput(props, ref) {
  const { label, ...otherProps } = props;
  return (
    <label>
      {label}
      <input {...otherProps} ref={ref} />
    </label>
  );
});

在父组件中,通过 ref 属性绑定子组件, 后续便可以通过绑定的 ref 变量来操作子组件中实际的 DOM 元素。如获取元素长度宽度,使元素聚焦的方法。

App.js

jsx 复制代码
function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
  }

  return (
    <form>
      <MyInput label="Enter your name:" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}

获取子组件中的暴露的函数

在一些场景下,可能需要从父组件中获取到自组件中定义的一些函数。实现这一功能也是通过 forwardRef 包裹函数组件,然后通过 useImperativeHandle 这个 hook 来暴露可被父组件调用的函数。

MyInput.js

jsx 复制代码
import { forwardRef, useRef, useImperativeHandle } from 'react';

const MyInput = forwardRef(function MyInput(props, ref) {
  const inputRef = useRef(null);

  useImperativeHandle(ref, () => {
    return {
      focus() {
        inputRef.current.focus();
      },
      scrollIntoView() {
        inputRef.current.scrollIntoView();
      },
    };
  }, []);

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

在父组件中,通过 ref 属性来操作子组件暴露的函数。

App.js

jsx 复制代码
import { useRef } from 'react';
import MyInput from './MyInput.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
    // This won't work because the DOM node isn't exposed:
    // ref.current.style.opacity = 0.5;
  }

  return (
    <form>
      <MyInput placeholder="Enter your name" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}

参考链接

相关推荐
hackeroink25 分钟前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者2 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-2 小时前
验证码机制
前端·后端
燃先生._.3 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖4 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235244 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240255 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar5 小时前
纯前端实现更新检测
开发语言·前端·javascript
寻找沙漠的人6 小时前
前端知识补充—CSS
前端·css