user11092881
user11092881

Reputation:

ref.current is always undefined when using ref from forwardRef

import React, { useRef } from "react";
import { render } from "react-dom";

const styles = {
  fontFamily: "sans-serif",
  textAlign: "left"
};

const Wrapper = () => {
  const ref = useRef();
  return <App ref={ref} />;
};

const App = React.forwardRef(
  ({ placeHolder, onNameSelected, error, onSuggestion }, ref) => {
    ref.current.setAttribute("he-de-data", "");

    return (
      <div style={styles}>
        <h4>Username</h4>
        <input ref={ref} />
      </div>
    );
  }
);

render(<Wrapper />, document.getElementById("root"));

Here's a sandbox that can help you out:

I have the following code, but ref.current is undefined. I need to use the ref from forwardRef and use that ref to add some attribute to the DOM. However, the ref.current is always undefined. Is there a particular reason for that?

Upvotes: 2

Views: 8606

Answers (2)

Sujit.Warrier
Sujit.Warrier

Reputation: 2889

First of all you are using ref and forwardRef incorrectly.

forwardRef is used because functional components cant be instantiated so if you assign a ref to any functional component you created it will be null. what forwardRef does is it forwards the ref to the component it is wrapping and then you can assign it to any html element inside your component, there by giving you access to the DOM from the PARENT .

What you want to do is to set the attribute from within the component itself and not from the parent. so forward ref is not required

 const Comp =({ placeHolder, onNameSelected, error, onSuggestion }) => {
       const inputRef = useRef(null);
       useEffect(()=>{
          if(inputRef.current!==null)
          inputRef.current.setAttribute("he-de-data", "");
        },[]);

    return (
      <div style={styles}>
        <h4>Username</h4>
        <input ref={inputRef} />
      </div>
    );
  }

https://codesandbox.io/embed/react-16-v0kn4?fontsize=14&hidenavigation=1&theme=dark

Upvotes: 5

topched
topched

Reputation: 775

ref.current will be undefined on the first render. Its needs to create all the dom nodes + children before it can assign the ref. You can guard against it with something like

let inner = null;
if (ref.current !== undefined) {
    // do whatever you want with the ref here
}

Also you may want to check you logic when assigning inner. setAttribute doesnt return anything

Upvotes: 0

Related Questions