React createRef:通过引用对象,在父组件中操作子组件

一 代码

 

在MyComponent中,操作其子组件(文本框)。

import React from 'react';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef(); // 将引用对象设置为父组件的成员
  }

 render() {
    return <input type="text" ref={this.inputRef} />;
 }

  componentDidMount() {
    console.log(this.inputRef); // {current: input}
    console.log(this.inputRef.current); // <input type="text">
    console.log(this.inputRef.current instanceof HTMLInputElement); // true
    this.inputRef.current.focus(); // 操作子组件
  }
}

  

二 原理

 

React.createRef函数会创建一个引用对象(只有一个current属性)。

扫描二维码关注公众号,回复: 5372111 查看本文章
// react安装包中的react.development.js
// an immutable object with a single mutable(易变的) value
function createRef() {
  var refObject = {
    current: null
  };
  {
    Object.seal(refObject); // 将对象密封(不能增删属性、配置属性,但可以给属性赋值)
  }
  return refObject;
}

子组件创建完成后,会检测其props输入属性中的ref属性,并做相应的处理。

// react-dom安装包中的react-dom.development.js

function commitAttachRef(finishedWork) {
  var ref = finishedWork.ref;
  if (ref !== null) {
    var instance = finishedWork.stateNode;
    var instanceToUse = void 0;
    switch (finishedWork.tag) {
      case HostComponent: // 原生html标签
          // 原样返回:function getPublicInstance(instance) {return instance;}
        instanceToUse = getPublicInstance(instance);
        break;
      default:
        instanceToUse = instance; // React组件
    }
    if (typeof ref === 'function') { // ref是函数
      ref(instanceToUse); // 执行
    } else { // ref是引用对象
      {
        if (!ref.hasOwnProperty('current')) {
          warningWithoutStack$1(
        false, 
        'Unexpected ref object provided for %s. ' 
          + 'Use either a ref-setter function or React.createRef().%s', 
        getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
        }
      }

      ref.current = instanceToUse; // 设置引用对象的current属性
    }
  }
}

引用对象是父组件的成员,于是父组件可以通过引用对象操作子组件。

猜你喜欢

转载自www.cnblogs.com/sea-breeze/p/10457312.html