Skip to content

React 中的 forwardsRef,作用是什么, 有哪些使用场景?

参考答案:

在 React 中,forwardRef 是一个高阶组件(HOC),用于**转发引用(ref)**到子组件的 DOM 元素或子组件内部的某个实例上。通常,React 的 ref 是用来直接访问 DOM 元素或组件实例的,但是在函数组件中,ref 是无法直接使用的,因为函数组件没有实例。

forwardRef 允许我们在函数组件中传递 ref,将其绑定到组件内部的 DOM 元素或组件实例上,从而能够在父组件中访问这个子组件的 DOM 或实例方法。

1. forwardRef 的作用

forwardRef 使得我们能够将 ref 从父组件转发到子组件中,使得父组件能够访问子组件的内部 DOM 元素或方法。

2. forwardRef 的语法

forwardRef 接受一个函数组件,并返回一个新的组件,该组件会接收 ref 参数并将其转发到子组件。

jsx
import React, { forwardRef } from 'react';

// 使用 forwardRef 创建一个转发 ref 的组件
const MyButton = forwardRef((props, ref) => {
  return <button ref={ref}>{props.children}</button>;
});

export default MyButton;

在上面的例子中,MyButton 组件是一个函数组件,接受 propsref 作为参数。forwardRefref 转发到 <button> 元素上。

3. 使用场景

场景 1:访问子组件的 DOM 元素

父组件想要直接访问子组件的 DOM 元素或执行某些操作(例如聚焦某个输入框)。

jsx
import React, { useRef } from 'react';
import { forwardRef } from 'react';

// 定义一个转发 ref 的函数组件
const Input = forwardRef((props, ref) => {
  return <input ref={ref} {...props} />;
});

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

  const handleFocus = () => {
    inputRef.current.focus();  // 访问子组件的 DOM 元素,执行聚焦操作
  };

  return (
    <div>
      <Input ref={inputRef} />
      <button onClick={handleFocus}>Focus Input</button>
    </div>
  );
}

export default ParentComponent;

在这个例子中,Input 组件通过 forwardRef 转发 ref,让父组件能够直接访问并操作 <input> 元素,例如聚焦。

场景 2:将 ref 转发到第三方库的组件

在使用第三方库时,通常我们需要通过 ref 来获取其组件的 DOM 元素或实例方法。如果该库的组件是一个函数组件,而不是类组件,ref 默认是无法传递的。此时可以使用 forwardRef 来实现。

例如,第三方库中的一个组件:

jsx
// ThirdPartyComponent.js
import React from 'react';

function ThirdPartyComponent() {
  return <div>Some third party component</div>;
}

export default ThirdPartyComponent;

如果我们想要通过 ref 访问这个 div,就可以使用 forwardRef 进行封装:

jsx
// WrappedComponent.js
import React, { forwardRef } from 'react';
import ThirdPartyComponent from './ThirdPartyComponent';

const WrappedComponent = forwardRef((props, ref) => {
  return <ThirdPartyComponent ref={ref} {...props} />;
});

export default WrappedComponent;

场景 3:高阶组件中的 ref 转发

在某些高阶组件中,我们需要将 ref 转发到被包装组件的根元素。这样父组件可以使用 ref 获取到子组件的 DOM 元素。

jsx
import React, { forwardRef } from 'react';

function withExtraStyles(Component) {
  return forwardRef((props, ref) => {
    return <Component ref={ref} {...props} style={{ color: 'red' }} />;
  });
}

const Button = (props) => {
  return <button {...props}>Click me</button>;
};

const StyledButton = withExtraStyles(Button);

function Parent() {
  const buttonRef = React.useRef();

  const handleClick = () => {
    console.log(buttonRef.current); // 访问按钮的 DOM 元素
  };

  return (
    <div>
      <StyledButton ref={buttonRef} onClick={handleClick} />
    </div>
  );
}

在这个例子中,withExtraStyles 是一个高阶组件(HOC),它通过 forwardRefref 转发到 Button 组件,并在 StyledButton 中添加样式。

题目要点:

forwardRef 是 React 中用来 转发引用(ref) 的一个功能。它使得父组件能够直接访问子组件中的 DOM 元素或方法。常见的使用场景包括:

  • 访问子组件的 DOM 元素:例如,在父组件中通过 ref 访问子组件的输入框并进行操作(如聚焦、获取值等)。
  • 与第三方库兼容:通过 forwardRefref 传递给第三方库的组件,确保父组件能够访问其 DOM 元素。
  • 高阶组件中转发 ref:在高阶组件中,通过 forwardRefref 转发到被包装组件的根元素,避免 ref 无效的问题。

使用 forwardRef 使得函数组件也能够支持 ref,并且能够灵活地控制组件的行为,尤其是在涉及到 DOM 操作或与其他库交互时。