import React from ‘react‘ export default class RefDemo extends React.Component { constructor() { super() this.objRef = React.createRef() } componentDidMount() { setTimeout(() => { this.refs.stringRef.textContent = ‘string ref got‘ this.methodRef.textContent = ‘method ref got‘ this.objRef.current.textContent = ‘obj ref got‘ }, 1000) } render() { return ( <> <p ref="stringRef">span1</p> <p ref={ele => (this.methodRef = ele)}>span3</p> <p ref={this.objRef}>span3</p> </> ) } }
<p ref="stringRef">span1</p>
=>
this.refs.stringRef.textContent = ‘string ref got‘
也就是我们想要获取的这个节点的 props 上面使用一个 ref 属性,然后传入一个字符串,传入这个字符串之后呢,react 在完成这一个节点的渲染之后,他会在 this.refs 这个对象上面挂载这个 string 对应的一个 key 。那么这个 key 他所指向的就是我们这个节点他的实例的对象。如果是 dom 节点,他就对应 dom 的实例,如果是子组件就会是子组件的实例,就是我们的 class component。如果是 function component 怎么办呢,正常来讲,他是会失败的,也就是拿到的会是个 undefined 。因为 function component 没有实例。这是第一种使用的方式,也是 v16 之前用的最多的方式。也是最不被推荐的一种方式。在下一个大版本之中会被废弃的一种方式
<p ref={ele => (this.methodRef = ele)}>span2</p> => this.methodRef.textContent = ‘method ref got‘
这个我们的 ref 传入的是一个方法,这个方法会接收一个参数,这个参数就是这个节点对应的实例,如果是 dom 节点对应的是 dom 的实例,如果是组件对应的是组件的实例。然后我们可以自己去this上面去挂载某一个属性,比如在这里,对应的是 methodRef 。
this.objRef = React.createRef() 这个 api 就是 React.createRef(),这个对象其实就是这样的 { current: null } 。然后这个对象传入给某一个节点 <p ref={this.objRef}>span3</p>
在组件渲染完成之后,会把这个节点对应的实例挂载到这个对象的 current 这个属性里面,我们要调用他就是通过
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * @flow */ import type {RefObject} from ‘shared/ReactTypes‘; // an immutable object with a single mutable value export function createRef(): RefObject { const refObject = { current: null, }; if (__DEV__) { Object.seal(refObject); } return refObject; }
点开源码,震惊了,非常的少。 也非常的简单,他返回的就是这样一个对象 refObject 。他里面 current 是 null 。如果是开发状态下 Object.seal(refObject) 。refObject 这个对象被封闭,阻止添加新属性并将现有属性标记为不可配置。当前属性的值只要可写就可以改变
原文:https://www.cnblogs.com/wzndkj/p/11938192.html