reactjsreact-hooks

React Accessing another component’s DOM nodes


Going through react.dev learning tutorial, I noticed something not quite right about accessing another component’s DOM nodes.

https://react.dev/learn/manipulating-the-dom-with-refs#accessing-another-components-dom-nodes

As described in the above URL

However, if you try to put a ref on your own component, like < MyInput />, by default you will get null. Here is an example demonstrating it. Notice how clicking the button does not focus the input:

If I run the example in the sandbox there is no warning about function components cannot be given refs.

The code runs normally and the input got focus.

I even downloaded the sandbox and ran it on my local development environment but I got the same result.

My guess is the ref attribute is treated as a normal prop which is sent to the MyInput component and get destructred and become the ref attribute of < input >.

It is the same as the following code

import { useRef } from "react";

function MyInput({myCustomRef}) {
  return (
    <>
      <label>Name:</label>
      <input ref={myCustomRef} />
    </>
  );
}

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

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

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

But if so then that means tutorial is wrong which is unexpected considering the high quality of the rest of the tutorial.


Solution

  • That's because the sandbox is now running React 19 (released on Dec 05th 2024), where forwardRef is no longer needed, and using the ref prop now works:

    New function components will no longer need forwardRef, and we will be publishing a codemod to automatically update your components to use the new ref prop. In future versions we will deprecate and remove forwardRef.

    So, it seems as though that part of the React docs hasn't been updated yet to reflect the new behaviour, as it's still talking about the behaviour you would see if running React 18 and lower.

    So if you're using React 19, then you can ignore that part and instead follow their description of the ref prop from the React 19 change logs:

    Starting in React 19, you can now access ref as a prop for function components:

    function MyInput({placeholder, ref}) {   
      return <input placeholder={placeholder} ref={ref} /> 
    }
    
    //... <MyInput ref={ref} />