继续学习写源码系列,本系列是学习系列。
- 简单手写实现 React 的 createElement 和 render,里面有准备工作,不再赘述。
- 简单手写实现 react 的函数组件
- 简单手写实现 react 的类组件
- 简单手写实现 React 类组件的 state 更新
- 简单手写实现 React 类组件的 state 批量更新
- 简单手写实现元素的 Ref
本文的目标是,手写实现类组件的Ref。
TL;DR
- createRef 仍然简单的返回
{current:null} - 类组件身上的
ref,指向的就是{current:null},解析属性的时候,其current赋值为类组件的实例
准备工作
先将index.js的点击事件略微修改
// import React from './source/react';
// import ReactDOM from './source/react-dom';
import React from 'react';
import ReactDOM from 'react-dom';
class Form extends React.Component {
constructor(props) {
super(props);
this.textInputRef = React.createRef();
}
getFocus = () => {
// this.textInputRef.current指的是TextInput类的实例,实例有getFocus方法
this.textInputRef.current.getFocus();
};
render() {
return (
<>
<TextInput ref={this.textInputRef} />
<button onClick={this.getFocus}>获得焦点</button>
</>
);
}
}
class TextInput extends React.Component {
constructor(props) {
super(props);
this.input = React.createRef();
}
getFocus = () => {
this.input.current.focus();
};
render() {
return <input ref={this.input} />;
}
}
ReactDOM.render(<Form />, document.getElementById('root'));
点击获得焦点,输入框获得焦点:
分析 ref
<TextInput ref={this.textInputRef} />其实本质就是将this.textInputRef赋值为TextInput类的实例React.createRef()的返回值始终一致就是{current:null}(元素的时候说过)
实现
1.解析 ref 属性的时候,赋值当前类组件实例
这个也简单,props 属性解析的时候,赋值就好
// react-dom.js
const handleClassType = (vdom) => {
const { type: classFn, props } = vdom;
const instance = new classFn(props);
// props.ref在的话,将实例赋值到ref上 {props:{ref:{current:null}}
props.ref && (props.ref.current = instance);
// ...
};
老规矩,index.js打开自己文件的路径
正常运行,✌️~~~