React的React.createRef()/forwardRef()源码解析(三)

时间:2022-06-11 21:53:45

1.refs三种使用用法

1.字符串

1.1 dom节点上使用 获取真实的dom节点

    //使用步骤:
1. <input ref="stringRef" />
2. this.refs.stringRef
//值:<input />

1.2 类组件上使用 获取引用类组件的实例

    //使用步骤
1. <Child ref="compStringRef" />
2.this.refs.compStringRef
//值:{props:{},refs:{},state:null,....}

  2.回调函数

2.1 dom节点上挂载回调函数 函数的入参为dom节点

    //使用步骤
1.<input ref={(ref) => { this.callBackRef = ref }} />
2.this.callBackRef //值:<input />

2.2 类组件上挂载回调函数 函数的参数为类组件实例

    //使用步骤
1.<Child ref={(com) => { this.comCallbackRef = com }} />
2.this.comCallbackRef

3.CreateRef方法

3.1 React.createRef()创建一个ref  赋值给一个变量 使用ref.current属性获取dom节点

    //使用步骤
1.this.myCreateRef = React.createRef();
2. <input ref={this.myCreateRef} />
3.this.myCreateRef.current

3.2 React.createRef()创建一个ref 赋值给一个变量 使用ref.current属性获取类组件实例

    //使用步骤
1.this.myCompCreateRef = React.createRef()
2.<Child ref={this.myCompCreateRef} />
3.this.myCompCreateRef.current

2.React.forwardRef()使用用法

1.为啥会出现forwardRef()?

对于函数类型 function(props){return(<div>1111</div>)}  无法获取ref的值  如果要获取ref的值 必须要把ref传递进去

2.获取函数组件的实例

   //使用步骤
1.this.myCompCreateRef = React.createRef();
2.<Child ref={this.myCompCreateRef} />
3.this.myCompCreateRef.current
4.const Child = React.forwardRef((props, ref) => (
<input ref={ref} />
)); //平时组件传递 只能传递props 调用forwardRef 可以传递第二个参数ref

3.React.createRef()源码解析

  //返回一个具有current属性的refObject对象
function createRef() {
var refObject = {
current: null
};
{
Object.seal(refObject);
}
return refObject;
}

4.React.forwardRef()源码解析

  function forwardRef(render) {
{
if (render != null && render.$$typeof === REACT_MEMO_TYPE) {
warningWithoutStack$1(false, 'forwardRef requires a render function but received a `memo` ' + 'component. Instead of forwardRef(memo(...)), use ' + 'memo(forwardRef(...)).');
} else if (typeof render !== 'function') {
warningWithoutStack$1(false, 'forwardRef requires a render function but was given %s.', render === null ? 'null' : typeof render);
} else {
!( // Do not warn for 0 arguments because it could be due to usage of the 'arguments' object
render.length === 0 || render.length === 2) ? warningWithoutStack$1(false, 'forwardRef render functions accept exactly two parameters: props and ref. %s', render.length === 1 ? 'Did you forget to use the ref parameter?' : 'Any additional parameter will be undefined.') : void 0;
} if (render != null) {
!(render.defaultProps == null && render.propTypes == null) ? warningWithoutStack$1(false, 'forwardRef render functions do not support propTypes or defaultProps. ' + 'Did you accidentally pass a React component?') : void 0;
}
}
//返回一个对象,对象里面包含一个$$typeof属性 它依然是ReactElement 使用时候:React.createElement(React.forwardRef(Child))
//该对象在传入ReactElement方法之后,保存在type属性里 而$$typeof仍然是REACT_ELEMENT_TYPE
return {
$$typeof: REACT_FORWARD_REF_TYPE,
render: render
};
}