在react典型的数据流中,props
传递是父子组件交互的唯一方式;通过传递一个新的props
值来使子组件重新re-render
,从而达到父子组件通信。当然,就像react官网所描述的一样,在react典型的数据量之外,某些情况下(例如和第三方的dom库整合,或者某个dom元素focus等)为了修改子组件我们可能需要另一种方式,这就是ref
方式。
ref 简介
React提供的这个ref
属性,表示为对组件真正实例的引用,其实就是ReactDOM.render()返回的组件实例
;需要区分一下,ReactDOM.render()
渲染组件时返回的是组件实例;而渲染dom元素时,返回是具体的dom节点。
转载:https://blog.csdn.net/qq20004604/article/details/79318244
在 Vue 中,ref 绑定的 DOM 元素,可以直接在组件实例里,通过 this.$refs.xxx
来获取。
但是在 React 中,ref 的属性的值,是一个函数;
函数的参数是当前 DOM 标签,或是组件实例;
于是你可以在函数体内,通过 this.xxx = xxxx
来将该 DOM 赋值给组件的某个变量。
这样就实现了类似 Vue 的 refs 的功能。
给一个示例:
class RefsDemo extends React.Component {
constructor() {
super()
this.state = {
display: ''
}
}
render() {
return <div>
<div type="text" ref={(input) => {
this.textInput = input
}}></div>
</div>
}
componentDidMount() {
console.log(this.textInput)
}
}
输出结果:
<input type="text">
当然也可以用来获取子组件:
class ChildDemo extends React.Component {
render() {
return <p>123</p>
}
}
class RefsDemo extends React.Component {
constructor() {
super()
this.state = {
display: ''
}
}
render() {
return <div>
<ChildDemo ref={(child) => {
this.child = child
}}/>
</div>
}
componentDidMount() {
console.log(this.child)
}
}
输出:
ChildDemo {props: {…}, context: {…}, refs: {…}, updater: {…}, _reactInternalFiber: FiberNode, …}
父组件获取子组件的 DOM:
首先,我们知道, 不能 直接通过父元素传 props 属性,然后将该 DOM 赋值给这个属性;
所以我们可以用常规的方法:即父组件传一个赋值函数给子组件,然后子组件在 ref 中调用这个函数即可。
示例:
class ChildDemo extends React.Component {
render() {
return <div>
<input type="text" ref={this.props.getInput}/>
</div>
}
}
class RefsDemo extends React.Component {
render() {
return <div>
<ChildDemo getInput={this.getInput.bind(this)}/>
</div>
}
getInput(DOM) {
console.log(DOM)
this.myInput = DOM
}
}
如果熟悉 React 的基本功,那么写出以上代码是毫无难度的。
但是,getInput 这个方法其实并没有必要独立出来,因为他的逻辑很简单,所以完全可以直接将这个函数作为 props 直接传入子组件,这也就有了 React 的教程上的示例。
class ChildDemo extends React.Component {
render() {
return <div>
<input type="text" ref={this.props.getInput}/>
</div>
}
}
class RefsDemo extends React.Component {
render() {
return <div>
{/* 因为函数简单,所以直接写到这里,箭头函数自带绑定this到声明时的作用域 */}
<ChildDemo getInput={DOM => {
console.log(DOM)
this.myInput = DOM
}}/>
</div>
}
// 注释掉
// getInput(DOM) {
// console.log(DOM)
// this.myInput = DOM
// }
}