Reputation: 5401
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
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
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
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