Refs provides an easy way to access DOM elements and React component instances. Some instance methods can be enforced through Refs. For example, control the focus management of the input tag, control the playback management of the video component (
tag).

Three ways to create Refs

  1. String Refs. (obsolete and not recommended) on the labelrefThe assignment. The following
   <input ref="numberInput"></input>
Copy the code

You can then access this in the component:

this.refs.numberInput
Copy the code
  1. Creating the Refs variable (introduced in Act 16.3) is passed when building componentsReact.createRef()Create the ref variable and attach it to the instance tag.
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return<div ref={this.myRef} />; }}Copy the code

You can then get it in the component as follows

const node = this.myRef.current;
Copy the code
  1. React calls the Ref callback and passes in the DOM element when the component is mounted.
import React from "react";
export class CustomInput extends React.Component {
  constructor(props) {
    super();
    this.myInputRef = null;
    this.setMyInputRef = element => {
      this.myInputRef = element;
    };
  }

  render() {
    return(<div> <input ref={this.setMyInputRef} /> </div> ); }}Copy the code

The Ref callback is executed twice during the update process, the first time passing null because the component is not mounted. The second time you pass in the actual DOM element. In addition, the Ref callback, like other component event listeners such as onChange and onMouseMove, is best bound to this. Otherwise, function variables are created repeatedly.

Refs forwarding

It is common in real-world development to encounter access to an internal component (child component) or DOM element of an encapsulated component, such as a wrapper component that accesses a higher-order component. If you use a ref directly on a higher-order component, you refer to an instance of the higher-order component itself, which is obviously not what you expect. But there are two ways to solve this problem. The following illustrates both approaches with an example of automatic focalization of a CustomTextInput component.

  1. Ref callbacks are passed to higher-order components as component properties
import React from "react";
import { CustomTextInputHOC } from "./CustomTextInputHOC";

class CustomTextInput extends React.Component {
  constructor(props) {
    super();
    this.state = {
      text: "nihao"
    };
    this.inputRef = React.createRef();
  }
  onTextChange = event => {
    event.persist();
    this.setState({
      text: event.target.value
    });
  };
  onFocus = () => {
    this.inputRef.current.focus();
  };
  render() {
    return( <div> <input ref={this.inputRef} onChange={this.onTextChange} /> <div>{this.state.text}</div> </div> ); }}export default CustomTextInputHOC(CustomTextInput);
Copy the code

The CustomTextInputHOC component is defined as follows:

import React from "react";

export function CustomTextInputHOC(WrapComp) {
  return class extends React.Component {
    render() {
      const { createRefFunc, name } = this.props;
      return<WrapComp ref={createRefFunc} name={name} />; }}; }Copy the code

Mount the CustomTextInput component in your App:

export default function App() {
  let inputRef = null;

  const createRef = ref => {
    inputRef = ref;
  };
  useEffect(() => {
    console.log(inputRef);
    inputRef.onFocus();
  });
  return <CustomTextInput createRefFunc={createRef} />;
}
Copy the code
  1. throughReact.forwardRefHijack the ref variable and pass it down.

The CustomTextInput component is the same as the above implementation. The CustomTextInputHOC component is implemented as follows:

import React from "react";
export function CustomTextInputHOC(WrapComp) {
  class MyComp extends React.Component {
    render() {
      const { forwardRef, name } = this.props;
      return<WrapComp ref={forwardRef} name={name} />; }}return React.forwardRef((props, ref) => {
    return<MyComp {... props} forwardRef={ref} />; }); }Copy the code

Mount the CustomTextInput component on the root node

export default function App() {
  let inputRef = React.createRef();
  useEffect(()=> {
   inputRef.current.onFocus();
  })
  return <CustomTextInput ref={inputRef} />;
}
Copy the code

reference

Refs forward

Refs and DOM