在 React 中,函数组件没有实例,因此传统的 ref
机制(用于访问类组件实例的方法)不适用。不过,可以通过以下几种方式在函数组件中使用 ref
来访问 DOM 元素或函数组件的内部逻辑:
1. 访问 DOM 元素
对于函数组件中引用 DOM 元素,可以使用 useRef
来创建一个 ref,并将其绑定到 DOM 元素上:
import React, { useRef, useEffect } from "react";
const MyComponent = () => {
const inputRef = useRef(null);
useEffect(() => {
// 访问 DOM 元素
if (inputRef.current) {
inputRef.current.focus(); // 例如,设置焦点
}
}, []);
return <input ref={inputRef} />;
};
2. 使用 forwardRef
转发 Ref
要在函数组件中访问子组件的 DOM 元素或通过 ref 传递组件实例,可以使用 React.forwardRef
来转发 ref:
import React, {
forwardRef,
useRef,
useImperativeHandle,
useEffect,
} from "react";
// 子组件使用 forwardRef 来接收父组件的 ref
const ChildComponent = forwardRef((props, ref) => {
const localRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
if (localRef.current) {
localRef.current.focus();
}
},
}));
return <input ref={localRef} />;
});
// 父组件使用 ref 来访问子组件的方法
const ParentComponent = () => {
const childRef = useRef();
useEffect(() => {
// 调用子组件的 focus 方法
if (childRef.current) {
childRef.current.focus();
}
}, []);
return <ChildComponent ref={childRef} />;
};
3. useImperativeHandle
的作用
useImperativeHandle
钩子允许你定制通过 ref 访问的实例值。例如,可以将特定的方法暴露给父组件,通过 ref 调用这些方法:
import React, { useRef, useImperativeHandle, forwardRef } from "react";
const CustomInput = forwardRef((props, ref) => {
const localRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
localRef.current.focus();
},
}));
return <input ref={localRef} {...props} />;
});
const ParentComponent = () => {
const inputRef = useRef();
const handleClick = () => {
if (inputRef.current) {
inputRef.current.focus();
}
};
return (
<div>
<CustomInput ref={inputRef} />
<button onClick={handleClick}>Focus Input</button>
</div>
);
};