The use of ref in react (useRef, forwardRef, useImperativeHandle, createRef)

Article directory

  • 1. What is ref
  • 2. Use ref in functional components
    • 1. useRef to get dom
    • 2. forwardRef gets the dom of the subcomponent
    • 3. useImperativeHandle exposes certain specified behaviors to the parent component
  • 3. Use ref in class components
    • 1. createRef
    • 2. Callback function
    • 3. String

1. What is ref

In React, ref is an object used to access a real DOM node or React component instance. It allows you to directly manipulate DOM elements or components within the component without following the traditional data flow.

Using ref you can:

  1. Access and manipulate the DOM: ref allows you to access and modify the real DOM by passing the ref object to the elements in the component. You can use ref to get the value of the input box, change the style of the element, add/delete/update elements, etc.

  2. Accessing and calling component methods: ref allows you to access methods defined on the component class. This is useful for situations where you need to access child component methods directly from the parent component.

  3. Getting component instances and event listening: When using class components, ref can be used to get the instance of the component so that other operations can be performed when needed. You can also use ref for event listening, such as performing certain operations when a specific event occurs.

It should be noted that in most cases, it is best to follow React’s data flow principles and try to avoid directly manipulating the DOM or accessing subcomponent methods. You should use ref only when there is no other suitable alternative and it is really necessary. Because direct manipulation of the DOM or methods of accessing subcomponents may destroy the encapsulation and reusability of the component.

2. Use ref in functional components

1. useRef to get dom

In React, functional components use the ref attribute to obtain an instance of the component or a reference to a Dom element. Using ref allows you to control components or Dom elements more conveniently, and you can access and modify their properties and methods when needed.

To use refs in functional components, you can use the useRef hook function provided by React. As an example, suppose we have a functional component MyComponent that contains an input element:

import React, {<!-- --> useRef } from 'react';

const MyComponent = () => {<!-- -->
  const inputRef = useRef(null);

  const handleClick = () => {<!-- -->
    // Use the ref object returned by useRef to access the properties and methods of input
    console.log(inputRef.current.value);
    inputRef.current.focus();
  };

  return (
    <div>
      <input ref={<!-- -->inputRef} type="text" />
      <button onClick={<!-- -->handleClick}>Focus Input</button>
    </div>
  );
};

export default MyComponent;

In the above example, we use the useRef hook function to create a reference named inputRef. We pass this reference to the ref attribute of the input element, so that the reference to the input can be obtained through inputRef.current.

In the handleClick function of the functional component, we can access the input element and get its value through inputRef.current. We can also use inputRef.current.focus() to give the input element the focus.

By using ref, we can easily manipulate components or Dom elements and perform operations that require accessing or modifying properties and methods.
Note that ref can only be used in functional components and cannot be used on subcomponents of functional components

2. forwardRef gets the dom of the subcomponent

In React, you can use ref on child components of functional components using forwardRef. The forwardRef function can pass ref to a child component, thereby using ref in the child component.

Here is an example showing how to use ref in a child component of a functional component:

import React, {<!-- --> forwardRef } from 'react';
 
// Subassembly
const ChildComponent = forwardRef((props, ref) => {<!-- -->
  return (
    <input type="text" ref={<!-- -->ref} />
  );
});
 
// parent component
const ParentComponent = () => {<!-- -->
  //Create a ref
  const inputRef = React.createRef();
  // Use ref to pass to child components
  return (
    <div>
      <ChildComponent ref={<!-- -->inputRef} />
      <button onClick={<!-- -->() => inputRef.current.focus()}>Focus on the input box</button>
    </div>
  );
};
 
export default ParentComponent;

In the above example, ChildComponent is a functional component, passed inside by passing ref as the second parameter of forwardRef The input element. You can then create a ref in ParentComponent and pass it to ChildComponent. In this way, we can operate the input element of the child component in the parent component, such as calling the focus() method.

In the button’s onClick event handler, we can obtain the input element of the subcomponent through inputRef.current and call its focus() method focuses the focus on the input box.

3. useImperativeHandle exposes certain specified behaviors to the parent component

In React, functional components can expose certain specified behaviors to parent components by using the useImperativeHandle hook function. This is useful in some cases, such as restricting certain DOM behaviors so that the parent component can directly operate certain functions of the component.

Here is an example that demonstrates how to use useImperativeHandle to limit DOM behavior:

import React, {<!-- --> useRef, useImperativeHandle, forwardRef } from 'react';

// Subassembly
const ChildComponent = forwardRef((props, ref) => {<!-- -->
  const childRef = useRef(null);

  //Define functions to be exposed
  useImperativeHandle(ref, () => ({<!-- -->
    // Expose specific DOM behavior here
    focus: () => {<!-- -->
      childRef.current.focus();
    },
    // Expose specific DOM behavior here
    blur: () => {<!-- -->
      childRef.current.blur();
    }
  }));

  return <input ref={<!-- -->childRef} />;
});

// parent component
const ParentComponent = () => {<!-- -->
  const childRef = useRef(null);

  const handleFocus = () => {<!-- -->
    childRef.current.focus(); // The focus function of the child component is called by the parent component
  };

  const handleBlur = () => {<!-- -->
    childRef.current.blur(); // The blur function of the child component is called by the parent component
  };

  return (
    <div>
      <ChildComponent ref={<!-- -->childRef} />
      <button onClick={<!-- -->handleFocus}>Focus</button>
      <button onClick={<!-- -->handleBlur}>Blur</button>
    </div>
  );
};

export default ParentComponent;

In the example above, ChildComponent is a simple functional component that contains an element. By using the useImperativeHandle hook function and passing ref as the first parameter, we can define the function that needs to be exposed to the parent component (in this case focus and blur). This means that the parent component can reference the child component through ref, and then directly call the child component’s focus and blur functions.

In ParentComponent, create a childRef reference using useRef. Then, in the handleFocus and handleBlur functions, access the of the ChildComponent function component through childRef.current focus and blur functions to directly control the DOM behavior of sub-components.

In this way, we can control the DOM behavior of the child component through button clicks in the parent component, thereby achieving restrictions on DOM behavior.

3. Use ref in class components

1. createRef

In a class component, you can use React.createRef() to create a ref object, and then attach the ref object to an element of the component. The element can be referenced and modified through the ref object. operate.

Here is an example using ref:

import React from "react";

class MyComponent extends React.Component {<!-- -->
  constructor(props) {<!-- -->
    super(props);
    
    this.myDivRef = React.createRef(); // Create a ref object
  }
  
  handleClick = () => {<!-- -->
    this.myDivRef.current.style.backgroundColor = "blue"; // Use the ref object to reference the element and operate on it
  }
  
  render() {<!-- -->
    return (
      <div>
        <div ref={<!-- -->this.myDivRef}>Hello, world!</div> {<!-- -->/* Attach the ref object to the element */}
        <button onClick={<!-- -->this.handleClick}>Change Color</button>
      </div>
    );
  }
}

export default MyComponent;

In the above example, we first create a ref object myDivRef in the constructor of the class. We can then attach the ref object to this element by using myDivRef as the value of the ref attribute of the

element. In the handleClick method, we reference the element via this.myDivRef.current and change its background color to blue.

In this way, when the button is clicked, the handleClick method will be called, thereby changing the background color of the

element referenced by ref.

2. Callback function

Set ref through a callback function, in which the DOM element is assigned to the component’s instance attribute. In the instance of the component, the DOM element can be accessed through properties.

import React, {<!-- --> Component } from 'react';

class ExampleComponent extends Component {<!-- -->
  constructor(props) {<!-- -->
    super(props);
    this.myRef = null;
    this.setRef = element => {<!-- -->
      this.myRef = element;
    };
  }

  componentDidMount() {<!-- -->
    console.log(this.myRef); //Access DOM elements
  }

  render() {<!-- -->
    return <div ref={<!-- -->this.setRef}>Example</div>;
  }
}

3. String

Use the ref attribute of a string to get the DOM element. This method was supported before React v16.3, but it is obsolete in newer versions and is not recommended.

import React, {<!-- --> Component } from 'react';

class ExampleComponent extends Component {<!-- -->
  componentDidMount() {<!-- -->
    console.log(this.refs.myRef); // Access DOM elements
  }

  render() {<!-- -->
    return <div ref="myRef">Example</div>;
  }
}