Nigel Wilson
Nigel Wilson

Reputation: 35

Why is document.getElementById() returning null when there is an element with that Id?

I'm trying to build a navbar in React that has a child component Menu that renders one of two different versions of the menu depending on the width on the div that the Menu is rendered inside. There is also a logo and company name that take up a relatively constant amount of width in the navbar and the div that holds the menu grows and shrinks to adjust for screen width and aspect ratio changes. Anyway, that div that grows and shrinks I gave an id="menu-section" so that I could use document.getElementById("menu-section").offsetWidth; to grab the available width and use that in the function that decided which version of the menu to render. The trouble is I get a TypeError: Cannot read property 'offsetWidth' of null. Why would the document.getElementById("menu-section") be failing to find the div and returning null?

function Menu(props) {
    let availableWidthPx = document.getElementById("menu-section").offsetWidth;
    if (availableWidthPx > 600) {
        return expanded version;
    }
    return collapsed version
}

function Navbar(props) {
    render(){
        return (
            <nav className="navbar">
                ...
                <div id="menu-section">
                    <Menu />
                </div> 
            </nav>
        )
    }
}
export default Navbar;

Upvotes: 2

Views: 14467

Answers (4)

Shohin
Shohin

Reputation: 558

Because the DOM is not loaded yet. Here's how to fix it:

function Menu(props) {
  React.useEffect(() => {
    let availableWidthPx = document.getElementById("menu-section");
    if (availableWidthPx) {
      console.log(availableWidthPx.offsetWidth);
    }

  }, [])

 return <div>Hello</div>;
}

Also, your Navbar functional component needs just return, not render

Upvotes: 8

THG
THG

Reputation: 322

Function Navbar doesn't add anything to the DOM.

Upvotes: 0

Catalin Pirvu
Catalin Pirvu

Reputation: 175

You should also consider calling the Menu function after rendering, or define it in an afterRender() block.

Upvotes: 0

Quentin
Quentin

Reputation: 944439

Because there isn't an element with that ID until all the rendering has finished and the result added to the DOM … but you are trying to call it from the render method.

Upvotes: 1

Related Questions