前言:有时候我们封装一个组件,组件中需要使用父级传进来ref属性,来做一些事情,然而,简单通过props.ref是无法获取传递过来的ref属性的,怎么办呢?组件中又使用hoc进行了包裹,这时候传递ref作为属性传值能传递过来吗?
场景重现:
import { useRef, useState } from "react";
const MyInput = (props) => {
console.log(props.ref, 'ref') // undefined
return (
<div>
<div>状态: {props.status ? "聚焦" : "失焦"}</div>
<input ref={props.ref} type="text" />
</div>
);
};
export default function App() {
const inputRef = useRef();
const [status, setStatus] = useState(false);
function handleChange() {
if (!status) {
setStatus(true);
inputRef.current.focus();
} else {
setStatus(false);
inputRef.current.blur();
}
}
return (
<div style={{ textAlign: "center" }}>
<button style={{ margin: "20px" }} onClick={handleChange}>
点击改变聚焦
</button>
<MyInput ref={inputRef} status={status} />
</div>
);
}
点击按钮就报错了,原因就是传给子组件ref是undefined。
问题解决
react提供了一个名为forwardRef的api来解决这个问题。接收两个参数,一个是props,另一个就是传进来的ref。
import { forwardRef, useRef, useState } from "react";
const MyInput = forwardRef((props, ref) => {
return (
<div>
<div>状态: {props.status ? "聚焦" : "失焦"}</div>
<input ref={ref} type="text" />
</div>
);
});
export default function App() {
const inputRef = useRef();
const [status, setStatus] = useState(false);
function handleChange() {
if (!status) {
setStatus(true);
inputRef.current.focus();
} else {
setStatus(false);
inputRef.current.blur();
}
}
return (
<div style={{ textAlign: "center" }}>
<button style={{ margin: "20px" }} onClick={handleChange}>
点击改变聚焦
</button>
<MyInput ref={inputRef} status={status} />
</div>
);
}
问题成功解决。