3

I have a simple example

function Node() {
    const [hidden, setHidden] = useState(true);
    const inputRef = useRef(null)
    console.log(inputRef);
    return (
        <div>
            {!hidden && <h2 ref={inputRef}>Hello World</h2>}
            {hidden && <button onClick={() => setHidden(false)}>Show Child</button>}
        </div>
    )
}

Upon clicking the button, I would expect that the h2 DOM element is attached to my ref. However, I found that the ref.current is still null upon logging, but if I expand the object, it contains the DOM node.

How am I supposed to access the DOM element via my ref? At the time I want to reference it, for example inputRef.current.getBoundingClientRect(), it's always shown as null. Your help is much appreciated!

1
  • Your log is just to early, at the time it runs the ref hasn't been assigned yet, it'll be there in useEffect, you should put your logic there Commented Mar 15, 2021 at 13:35

2 Answers 2

3

You are trying to use the ref in the render phase, but the ref will be populate once React paint the screen, in the commit phase. So, call it in a useEffect or useLayoutEffect

// run synchronously after all DOM mutations
React.useLayoutEffect(() => {
  // do something with inputRef
}, [])
Sign up to request clarification or add additional context in comments.

2 Comments

What if I want to display the coordinates of my ref in my render? Will I need to somehow force another render? For example, I want to have <div>{inputRef.current.getBoundingClientRect().width}</div>
yeah, you need to set state in the use effect with the value from inputRef.current.getBoundingClientRect().width
0

Your ref is not initialize when setHidden set to false if you want to use it you need some interactions like this

        import React, { useRef, useState, useEffect } from 'react';
    
    function App() {
        const [hidden, setHidden] = useState(true);
        const inputRef = useRef(null)
        console.log(inputRef);
        const handleChange=()=>{
        console.log(inputRef);
          
        }

useEffect(()=>{
   console.log(inputRef);
},[hidden])
        return (
            <div>
              <input onChange ={handleChange}></input>
                {!hidden && <h2 ref={inputRef}>Hello World</h2>}
                {hidden && <button onClick={() => setHidden(false)}>Show Child</button>}
            </div>
        )
    }
    
    export default App;

3 Comments

you are calling consle.log(inputRef) too early before code reachs {!hidden && <h2 ref={inputRef}>Hello World</h2>}
What if I want to display the coordinates of my ref in my render? Will I need to somehow force another render? For example, I want to have <div>{inputRef.current.getBoundingClientRect().width}</div>
Maks your operation inside useEffect(()=>{},[hidden])

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.