在React等框架出现之前,web页面的交互是依靠操作DOM实现的,到了出现vdom概念出来,React和Vue等框架利用组件的状态管理,通过操作dom的js对象,来实现页面的变化渲染。在React的数据流中,是自上向下的props传递数据,我们可以通过props来让子组件重新渲染,然而实际场景中,我们还是需要按照我们的方式来操作元素的行为,这个时候就需要用到ref来获取某元素dom节点
比如:需要focus一个input输入框,让媒体播放
使用ref的方式:
1、通过字符串定义获取
2、通过回调函数的方式去使用
3、使用React.createRef()
1、通过字符串定义
<input type='text' ref='inputRef' />
//访问时
console.log(this.refs.inputRef)
这种方式已经不被react官方推荐了,会在将来的某个版本移除掉,推荐开发者使用回调的方式。

2、通过回调函数的方式去使用
class Home extends Component{
constructor(){
super()
}
render(){
return(
<div>
<input
ref={c => {
this.inputRef = c;}}
/>
</div>
)
}
}
上面栗子中,当我们使用ref时,回调函数会接收当前dom元素作为参数,当我们使用this.refs.inputRef时候,可以获取到该节点元素,调用原生DOM API实现input的聚焦等多种方法。
该回调函数会等组件挂载完毕之后,或者是ref属性发生变化的时候,回调函数就会被调用。
以上两种方法,可以思考下,为什么要废除掉字符串的引用,改为回调函数的方式的好处是什么?
实际场景中,当我们使用this.refs.inputRef是一个独立的dom元素,如果是属于字符串引用,那么是无法知道inputRef什么时候卸载,也无法合理的销毁,如果使用回调函数,即当发生父组件触发卸载,子组件触发回调函数,可以在此时将inputRef销毁掉。
3、使用React.createRef()
用React.createRef()创建refs,通过ref属性
class Home extends Component{
constructor(){
super()
this.inputRef = React.createRef()
}
render(){
return(
<div>
<input
ref={ this.inputRef}
/>
</div>
)
}
}
//使用
//this.inputRef.current.focus()
使用createRef方法,生成ref对象
render的时候,接收子组件或者dom元素的ref属性
用this.inputRef.current来获取这个节点元素
注意:不能在无状态组件中使用ref
因为ref引用的是组件的实例,无状态组件中是没有实例的。
function MyComponent() {
return <input />;
}
class Home extends React.Component {
render() {
return (
<MyComponent
ref={(input) => { this.textInput = input; }} />
);
}
}
//以上代码是无效的
但是function申明的组件内部还是可以使用ref的,只要这个ref不是用来访问function组件
function MyComponent (){
let inputRef = React.createRef()
return (
<div>
<input ref={inputRef} type='text'/>
</div>
)
}
//如何使用
//inputRef.current.focus()
网友评论