This is the 15th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Translate: beta.reactjs.org/learn/manip…

Because React already processes the DOM structure based on render’s output, your components won’t need to manipulate the DOM very often. However, there may be times when you need to manipulate DOM elements managed by React, for example, to focus on a node, scroll to the node, or calculate its width and height. React has no built-in method to do this, so you’ll need ref to point to the DOM node.

In this series of articles you will learn:

  • How do I access DOM nodes managed by React using the REF attribute
  • How to integrate JSXrefAttribute associated withuseRefhook
  • How do I access the DOM nodes of other components
  • In which case it is safe to modify the DOM managed by React

For an introduction to and examples of refs, see my previous series of articles, useRef, which is easy to parse

series

  • How do I manipulate the DOM using ref? (1) Use ref to access DOM node
  • How do I manipulate the DOM using ref? (2) Use examples
  • How do I manipulate the DOM using ref? (c) How to use the ref callback to manage the list of ref

Access another component’s DOM node

When you set a ref on a built-in component that will be output as a browser element such as , React sets the ref’s current property to the corresponding DOM node (such as the actual in the browser). However, if you try to place the ref on your own component, such as
, you will get NULL by default. Here is an example to demonstrate it, note that clicking the button does not focus on the input.

import { useRef } from 'react';

function MyInput(props) {
  return <input {. props} / >;
}

export default function MyForm() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
Copy the code

Clicking this button prints an error message to the console:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Warning: Cannot provide references to function components. Attempts to access this reference will fail. Do you mean use react.forwardref ()?

This happens because React by default does not allow components to access other components’ DOM nodes. Not even your own children! This is by design. The Refs is an escape pod and should be used with caution. Manually manipulating another component’s DOM node makes your code even more vulnerable.

Instead, components that want to expose their DOM nodes must opt in to this behavior. A component can specify that it “forwards” its references to one of its children. Here’s how MyInput uses the forwardRef API:

const MyInput = forwardRef((props, ref) = > {
  return <input {. props} ref={ref} />;
});
Copy the code

Here’s how it works:

  • <MyInput ref={inputRef} />Tell React to put the corresponding DOM node ininputRef.currentIn the. However, the MyInput component chooses whether to join or not, and by default, it does not.
  • MyInputComponents are used withforwardRefThe statement,This makes it accept the inputRef parameter from the upper level as the second ref parameter declared after props.
  • MyInputItself passes the ref it receives to its internal<input>.

Thus, clicking the button to focus the input does the trick:

import { forwardRef, useRef } from 'react';

const MyInput = forwardRef((props, ref) = > {
  return <input {. props} ref={ref} />;
});

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
Copy the code

It is a common pattern in design systems for low-level components such as buttons and inputs to forward their references to their DOM nodes. On the other hand, advanced components such as forms, lists, or pages typically do not expose their DOM nodes to avoid relying on the DOM structure.