一 代码

import React, { Component } from 'react';

class Box extends Component {
render() {
return <button>你好</button>;
}
} export default class MyComponent extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef(); // 将引用对象设置为父组件的成员
this.boxRef = React.createRef(); // 将引用对象设置为父组件的成员
}  render() {
return <div>
{/* ref属性设置在DOM组件上,current指向html元素 */}
<input type="text" ref={this.inputRef} />
{/* ref属性设置在普通组件上,current指向普通组件 */}
<Box ref={this.boxRef}/>
</div>
 } 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(); // 操作子组件
console.log(this.boxRef); // {current: Box}
console.log(this.boxRef.current); // Box
console.log(this.boxRef.current instanceof React.Component); // true
}
}

二 原理

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

// react安装包中的react.development.js
// an immutable object with a single mutable(易变的) value
function createRef() {
var refObject = {
current: null
};
{
Object.seal(refObject); // 将对象密封(不能增删属性、配置属性,但可以给属性赋值)
}
return refObject;
}

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

html标签中的key属性、ref属性,会被React特殊处理,不会出现在props属性中!

// 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属性
}
}
}

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

React createRef:引用的更多相关文章

  1. React.createRef()

    概述: 引用(Refs)提供了一个获得DOM节点或者创建在render方法中的React元素的方法: 在典型的React数据流中,props是唯一的父组件与它们的子元素的通信方式.更改子元素,你需要使 ...

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

    1.refs三种使用用法 1.字符串 1.1 dom节点上使用 获取真实的dom节点 //使用步骤: 1. <input ref="stringRef" /> 2. t ...

  3. react之引用echarts

    react之引用echarts npm: npm install echarts --save 代码: import React, { Component } from 'react'; // 引入 ...

  4. React中引用CSS样式的方法

    相对于html中引用css的三种方法,react中也有三种方法,一一相对: 1. 行内样式:直接在组件内部定义 <div style={{width:'20px',height:'30px'}} ...

  5. react.js 引用 NavBar 报错svg-spite-loader

    Navbar   iconName="false"  配置 改为  iconName={this.props.bool}

  6. React + TypeScript:元素引用的传递

    React 中需要操作元素时,可通过 findDOMNode() 或通过 createRef() 创建对元素的引用来实现.前者官方不推荐,所以这里讨论后者及其与 TypeScript 结合时如何工作. ...

  7. React forwardRef:跳转引用

    一 在DOM组件中使用 import React, { Component } from 'react'; // 跳转引用对象本身并不关心ref,而是由渲染函数转发ref const FancyBut ...

  8. [React] Reference a node using createRef() in React 16.3

    In this lesson, we look at where we came from with refs in React. Starting with the deprecated strin ...

  9. react中的DOM操作

    前面的话 某些情况下需要在典型数据流外强制修改子代.要修改的子代可以是 React 组件实例,也可以是 DOM 元素.这时就要用到refs来操作DOM 使用场景 下面是几个适合使用 refs 的情况 ...

随机推荐

  1. 在子页面操作父页面元素和iframe说明

    实现功能:在子页面操作父页面元素. 在实际编码的过程中,大家一定有这种需求:在父级页面有一个<iframe scrolling='auto'></iframe>内联框架,而我们 ...

  2. 第二章 JavaScript总结(下)

    js参考表 变量的引用 <script> var n=10; m = 10; //全局变量 function a () { var x = 10; //局部变量 b = 10;//全局变量 ...

  3. mysql:设置字符集utf8mb4 支持emoji字符

    为什么要把数据库的字符集设置成utf8mb4呢?以前一直用的都是utf8啊? 答案在这里:utf8适用于不使用移动设备的互联网交互,utf8mb4适用于当前的移动设备互联网开发,因为移动设备中常常会有 ...

  4. Spark Streaming 'numRecords must not be negative'问题解决

    转载自:http://blog.csdn.net/xueba207/article/details/51135423 问题描述 笔者使用spark streaming读取Kakfa中的数据,做进一步处 ...

  5. 关于Xilinx AXI Lite 源代码分析---自建带AXI接口的IP

    关于Xilinx AXI Lite 源代码分析---自建带AXI接口的IP 首先需要注意此处寄存器数量的配置,它决定了slv_reg的个数. 读写数据,即是对寄存器slv_reg进行操作: 关于AXI ...

  6. python 基本语句

    python 基本语句 在使用python的变量前必须给它赋值,因为python变量没有默认值. 获取用户输入值 此时需要注意:input函数的返回值为文本或字符串. 一些简单的函数 乘方 绝对值 将 ...

  7. sql server 2016 附加 其它目录的数据库

    如果数据库不在默认目录,那么需要将 mdf所在目录或者 mdf文件 添加 用户 [NT SERVICE\MSSQLSERVER]的创建权限,否则会提示没有权限, 具体详见: https://docs. ...

  8. 【浅色】最强Win7 x64评测

    [浅色]最强Win7 x64评测 [浅色]最强Win7 x86 & x64 | WINOS https://www.winos.me/archives/789.htmlESD671MB,安装后 ...

  9. python 使用ElementTree解析xml

    以country.xml为例,内容如下: <?xml version="1.0"?> <data> <country name="Liech ...

  10. hash的排序(转载)

    sort函数 sort LISTsort BLOCK LISTsort SUBNAME LIST sort 的用法有如上3种形式.它对LIST进行排序,并返回排序后的列表.假如忽略了SUBNAME或B ...