Carl Binalla
Carl Binalla

Reputation: 5401

Getting the height of an imported component

How to get the getBoundingClientRect() of an imported component? or at least access the elements inside

I can get it if it used inside the component itself

FixedTopNavigation.js

constructor(props) {
    super(props);
    this.state = {
        height: 0,
    }
}

componentDidMount() {
    console.log(this.topNav.getBoundingClientRect());
}
render() {
    return (
        <nav ref={(elem) => this.topNav = elem} id="topNav" className="fixed-top navbar navbar-expand-md navbar-light bg-light">
            <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#sideNav" aria-controls="navbarTogglerDemo03" aria-expanded="false" aria-label="Toggle navigation">
                <span className="navbar-toggler-icon"></span>
            </button>
            <a className="navbar-brand" href="/">Biometrics</a>
        </nav>

    )
}

But when used after importing that component in a different file:

Dashboard.js

constructor(props) {
    super(props);
    this.state = {
        height: 0,
    }
}

componentDidMount() {
    console.log(this.topNav.getBoundingClientRect());
}
render() {
    return (
        <FixedTopNavigation ref={(elem) => this.topNav = elem}/>
    )
}

Error received:

TypeError: this.topNav.getBoundingClientRect is not a function

After using console.log(), it seems that it is not returning the element anymore. All tutorials that I searched points to the first code syntax.

Also tried this.topNav = React.createRef(), but the error is still the same

Upvotes: 0

Views: 59

Answers (2)

Marcelo
Marcelo

Reputation: 1592

Theres some good ways to do what u want, like Redux, Context, a global variable, example: window.myApp.topNavBar.height = 100

I would probably go with this one:

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

class Target extends React.Component {
  render() {
    return <h1 className={this.props.className}>TARGET</h1>;
  }
}

class App extends React.Component {
  componentDidMount() {
    console.log(
      "RESULT: ",
      document.querySelector(".target").getBoundingClientRect()
    );
  }
  render() {
    return <Target className="target" />;
  }
}

render(<App />, document.querySelector(".root"));

U can even remove the property.
U can see this working here: https://codesandbox.io/s/5xx50pw984?fontsize=14

Edit

For those which are using a state manager like Redux, please avoid using this kind of code and try to put everything inside ur redux state. And I would recommend to avoid the react state. U can read this article

Upvotes: 1

Mihai Matei
Mihai Matei

Reputation: 24276

I think you could try something like this:

constructor(props)
{
    super(props);

    this.state = {
        height: 0,
    }
}

componentDidMount()
{
    this.setState({
        height: this.topNav.getBoundingClientRect()
    });
}

getHeight()
{
    return this.state.height;
}

render()
{
    return (
        <nav ref={(elem) => this.topNav = elem} id="topNav" className="fixed-top navbar navbar-expand-md navbar-light bg-light">
            <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#sideNav" aria-controls="navbarTogglerDemo03" aria-expanded="false" aria-label="Toggle navigation">
                <span className="navbar-toggler-icon"></span>
            </button>
            <a className="navbar-brand" href="/">Biometrics</a>
        </nav>

    )
}

And when you want to access the component's height then you would do something like:

constructor(props)
{
    super(props);

    this.state = {
        height: 0,
    }
}

componentDidMount()
{
    this.setState({
        height: this.topNav.getHeight()
    });
}

render()
{
    return (
        <FixedTopNavigation ref={(elem) => this.topNav = elem}/>
    )
}

Upvotes: 0

Related Questions