如果你需要在父组件中同时获取子组件的属性值和子组件内的 DOM 元素(例如 <input>
元素),可以通过在子组件中定义两个 ref
来实现:一个用于暴露子组件的实例方法,另一个用于直接操作 DOM 元素。
修改子组件
在子组件中,你可以定义两个 ref
:一个用于暴露实例方法,另一个用于操作 DOM 元素。然后通过 useImperativeHandle
将 DOM 元素的引用也暴露给父组件。
子组件
tsx
复制
import React, { useRef, useImperativeHandle } from 'react';
const ChildComponent = React.forwardRef((props, ref) => {
const [value, setValue] = React.useState("Hello, World!");
const inputRef = useRef<HTMLInputElement>(null); // 用于操作 DOM 元素的 ref
useImperativeHandle(ref, () => ({
getValue: () => value,
setValue: (newValue) => setValue(newValue),
getInputElement: () => inputRef.current, // 暴露 DOM 元素的引用
}));
return (
<div>
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
ref={inputRef} // 将 ref 附加到 input 元素上
/>
</div>
);
});
export default ChildComponent;
父组件
在父组件中,你可以通过 ref
调用子组件的 getInputElement
方法来获取 <input>
元素的引用。
父组件
tsx
复制
import React, { useRef, useEffect } from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
const childRef = useRef(null);
useEffect(() => {
// 确保子组件已经渲染完成
if (childRef.current) {
// 通过 ref 调用子组件的方法
const inputValue = childRef.current.getValue();
console.log('Input Value:', inputValue);
// 获取子组件的 input 元素
const inputElement = childRef.current.getInputElement();
if (inputElement) {
console.log('Input Element:', inputElement);
inputElement.focus(); // 例如,聚焦到输入框
}
}
}, []);
const changeChildValue = () => {
if (childRef.current) {
childRef.current.setValue("New Value from Parent");
}
};
return (
<div>
<ChildComponent ref={childRef} />
<button onClick={changeChildValue}>Change Child Value</button>
</div>
);
};
export default ParentComponent;