写在前面:ref 不是 prop 属性,就像 key 一样,其被 React 进行了特殊处理;如果你不熟悉refs的用法,请将前面的这句话牢牢记住!
一,直接使用ref
ref用于html元素上,current 指向该底层dom元素, ref用于类组件上, 则current指向类组件实例,你不可以使用ref在函数组件上,因为他没有实例!
1. createRef()
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
⚠️注意:👆上面说的是不能使用ref属性在函数组件上,但是在函数内部是可以通过useRef使用ref的,例如下面这样:
function CustomTextInput(props) {
// 这里必须声明 textInput,这样 ref 才可以引用它 const textInput = useRef(null);
function handleClick() {
textInput.current.focus(); }
return (
<div>
<input
type="text"
ref={textInput} />
<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}
2. 回调 Refs
它能助你更精细地控制何时 refs 被设置和解除
this.inputRef = null;
<input ref={(element) => this.inputRef = element} />
你可以随时随地的按照你想要的去更改this.inputRef=null,这就是上面说的更精细地控制何时 refs 被设置和解除
二,ref的传递
1.对于类组件
对于类组件因为ref直接获取的是实例,所以我们可以直接获取实例后调用其中的方法即可;
2.对于函数组件:
我们再次大声的读出来:“ref 不是 prop 属性,就像 key 一样,其被 React 进行了特殊处理”;
我们如果需要传递ref或者说获取子组件中的某个元素,我们需要通过React.forwardRef, 例如下面这样:
const FancyButton = React.forwardRef((props, ref1) => {
useImperativeHandle(ref1, () => ({
formValidate: () => xxx(), // 暴露给父组件调用的方法
}));
return (
<button ref={ref1} className="FancyButton"> // 将button这个ref传递出去
{props.children}
</button>
))
};
// You can now get a ref directly to the DOM button:
const ref1 = React.createRef();
<FancyButton ref={ref1}>Click me!</FancyButton>;
最后补一张思维导图: