react api:forwardRef

本文介绍了如何在React中使用forwardRef暴露组件的DOM节点给父组件,以及如何通过ref和useImperativeHandle实现命令式操作。同时强调了合理使用ref的原则,避免滥用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

forwardRef 允许组件使用 ref 将 DOM 节点暴露给父组件。

**
import { forwardRef } from ‘react’;

const MyInput = forwardRef(function MyInput(props, ref) {
// …
});

使用 forwardRef() 让组件接收 ref 并将其传递给子组件:

forwardRef 返回一个可以在 JSX 中渲染的 React 组件。与作为纯函数定义的 React 组件不同,forwardRef 返回的组件还能够接收 ref 属性。

const MyInput = forwardRef(function MyInput(props, ref) {
return (

);
});

props:父组件传递过来的 props。

ref:父组件传递的 ref 属性。ref 可以是一个对象或函数。如果父组件没有传递一个 ref,那么它将会是 null。你应该将接收到的 ref 转发给另一个组件,或者将其传递给 useImperativeHandle。
**

将 DOM 节点暴露给父组件

**
默认情况下,每个组件的 DOM 节点都是私有的。然而,有时候将 DOM 节点公开给父组件是很有用的,比如允许对它进行聚焦。将组件定义包装在 forwardRef() 中便可以公开 DOM 节点:

import { forwardRef } from ‘react’;

const MyInput = forwardRef(function MyInput(props, ref) {
const { label, …otherProps } = props;
return (

);
});
你将在 props 之后收到一个 ref 作为第二个参数。将其传递到要公开的 DOM 节点中:
import { forwardRef } from ‘react’;
const MyInput = forwardRef(function MyInput(props, ref) { const { label, …otherProps } = props; return ( );});
这样,父级的 Form 组件就能够访问 MyInput 暴露的 DOM 节点:
function Form() {
const ref = useRef(null);

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

return (



编辑


);
}

**

在多个组件中转发 ref

**
除了将 ref 转发到 DOM 节点外,还可以将其转发到自定义组件,例如 MyInput 组件:
const FormField = forwardRef(function FormField(props, ref) {
// …
return (
<>


</>
);
});
如果 MyInput 组件将 ref 转发给它的 ,那么 FormField 的 ref 将会获得该 :
function Form() {
const ref = useRef(null);

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

return (



Edit


);
}
**

暴露命令式句柄而非 DOM 节点

**
可以使用被称为 命令式句柄(imperative handle) 的自定义对象暴露一个更加受限制的方法集,而非整个 DOM 节点。为了实现这个目的需要定义一个单独的 ref 存储 DOM 节点:
const MyInput = forwardRef(function MyInput(props, ref) {
const inputRef = useRef(null);

// …

return <input {…props} ref={inputRef} />;
});
将收到的 ref 传递给 useImperativeHandle 并指定你想要暴露给 ref 的值:
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。只应在无法使用 props 表达的 命令式 行为中使用 ref:例如滚动到节点、将焦点放在节点上、触发动画,以及选择文本等等。

如果可以将某些东西使用 props 表达,那就不应该使用 ref。例如,不要从一个 Modal 组件中暴露像 { open, close } 一样的命令式句柄,更好的做法是将 isOpen 作为 prop,像这样 。Effect 可以帮助通过 props 暴露命令式行为。

我的组件使用了 forwardRef,但是它的 ref 总是为 null 。 这通常意味着你忘记实际使用你所接收到的 ref 了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值