[React Source Code] React-Ref && Forward-Ref

react-ref

Source code address: https://github.com/facebook/react/blob/master/packages/react/src /ReactCreateRef.js

Three ways to use ref

  • string ref (the method not recommended, obsolete)

React will mount a key corresponding to this string on the object this.refs after finishing the rendering of this node. This key points to the instance object of this node, if it is dom The node will correspond to an instance of dom. If it is a subcomponent, it will be an instance of a subcomponent (that is, a class component). If it is a function component, it will normally fail, which is undefined

  • function
  • createRef

Use createRef to create an object. When the object is initialized, the current inside is null, and the object is passed to a node, After the component is rendered, the node will be mounted to the object’s current

// demo
import React from'react'

export default class RefDemo extends React.Component {
constructor() {
super()
this.objRef = React.createRef()

// {current: null }
}

componentDidMount() {
// console.log(`span1: ${this.refs.ref1.textContent}`)
// console.log(` span2: ${this.ref2.textContent}`)
// console.log(`sp an3: ${this.ref3.current.textContent}`)
setTimeout(() => {
this.refs.stringRef.textContent ='string ref got'
this.methodRef. textContent ='method ref got'
this.objRef.current.textContent ='obj ref got'
}, 1000)
}

render() {< br /> return (
<>

span1


(this.methodRef = ele)}>span3


span3



)
}
}
< br />// export default () => {
// return
Ref

// }

Demo can see that all three methods are successful Get the node and update the value of the node

// Source code interpretation
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;
}

The source code is actually just a few lines, and one is returned Object, this object has a current attribute, initially null

store a question: how to use this object later, how to mount the node ?

forward-ref

Source learning address: https://github.com/facebook/react/blob/master/packages/react /src/forwardRef.js

Consider the following scenario

We are a component developer and have written many open source components for users to use . The user uses the connect connection component of redux, for example, connect is actually a hoc mode that wraps a layer of components, so if the user uses ref on the connect component, it cannot be directly mounted to the real component.

Therefore

You can consider using React.forwardRef(props, ref) to pass a layer of ref

// demo
import React from'react'

const TargetComponent = React.forwardRef((props, ref) => (

))

export default class Comp extends React.Component {
constructor() {
super()
this.ref = React.createRef()
}

componentDidMount() {
this.ref.current.value ='ref get input'
}

render() {< br /> return
}
}
// Source code interpretation
import {REACT_FORWARD_REF_TYPE} from'shared/ReactSymbols' ;

import warningWithoutStack from'shared/warningWithoutStack';

export default function forwardRef(
render: (props: Props , ref: React$Ref) => React$Node,
) {

...

return {
$$typeof : REACT_FORWARD_REF_TYPE,
render ,
};
}

/**
What is returned is an object. There is a $$typeof in the object, and it must not be the same as the $$typeof in createElement. Confuse.

Take the above demo as an example, because the object returned by React.forwardRef is an object, TargetComponent is also an object, and is parsed from jsx to js, ​​and parsed as React.createElement( In type, config, children), TargetComponent is only used as a type.

So

The $$typeof returned by React.forwardRef is still REACT_ELEMENT_TYPE, and its type is the object we got{
$$typeof: REACT_FORWARD_REF_TYPE,
render,
};
There is a $$typeof in it, which is REACT_FORWARD_REF_TYPE

Summary: We use React.forwardRef to create all the nodes, its $ $typeof is REACT_ELEMENT_TYPE

*/

Leave a Comment

Your email address will not be published.