背景
React中ref属性有两种使用场景:
- 绑定在普通元素上,用来获取元素DOM(比如下例中在点击事件内可以拿到input的dom,从而完成获取input值的操作,能够完成这种操作的基础就是ref)
- 绑定在组件上,用来获取组件实例
export default class DemoRef extends Component {
handle() {
let value = this.input.value;
console.log(value);
}
render() {
return (
<div>
<input type='text' ref={(input) => (this.input = input)} />
<button onClick={this.handle.bind(this)}>按钮</button>
<Alert ref={alert => (this.alert = alert)} />
</div>
);
}
}
思路
对于普通元素,在创建真实DOM元素后,若对应的virtual dom对象的props中存在ref函数,可以将生成的通过回调的方式传递出去。 对于组件,在创建类组件的render virtual dom时,可以获取到component实例,使用virtual dom的props.ref回调可以传递出去。
代码实现
在createDOMElement
中,创建完真实元素 newElement
后,可以将元素作为参数,通过ref回调传递出去
export default function createDOMElement(vdom) {
// 创建真实元素 newElement...
if (vdom.props?.ref) {
vdom.props?.ref(newElement);
}
}
在 mountComponent
中,类组件的render的virtual dom中存储了component实例,可以传递出去
export default function mountComponent (vdom, container, oldDOM) {
// 获取类组件render virtual dom...
if (renderedVDOM?.component && vdom.props?.ref) {
vdom.props?.ref(renderedVDOM?.component);
}
// 组件触发生命周期
renderedVDOM?.component?.componentDidMount();
}