Answer the question
In order to leave comments, you need to log in
What is the correct way to get the clientWidth of a DOM element after rendering?
There is a navigation component, at the moment it looks like this:
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import styles from './Nav.styl';
export default class Nav extends Component {
state = {
boundryOffset: 0,
boundryWidth: 0
}
updateBoundry = (target) => {
if (target && target.firstChild.classList.contains('active')) {
this.setState((prevState) => ({
...prevState,
boundryOffset: target.firstChild.offsetLeft,
boundryWidth: target.firstChild.clientWidth,
}))
}
}
render() {
return (
<nav ref="nav" className={styles.nav}>
<span
style={{
transform: `translateX(${this.state.boundryOffset}px)`,
width: `${this.state.boundryWidth}px`
}}
className={styles.boundry}></span>
<li className={styles.item}
ref={this.updateBoundry}>
<NavLink exact className={styles.link} to='/'>Home</NavLink>
</li>
<li className={styles.item}
ref={this.updateBoundry}>
<NavLink exact className={styles.link} to='/training'>Decks</NavLink>
</li>
</nav>
);
}
}
clientWidth
returns 0, but it’s offsetLeft
not clear where did 32 come from. I get the same results when I try to select these elements with normal selectors in the componentDidMount
hook, in other hooks and the console, the elements return the correct values.import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import styles from './Nav.styl';
import ReactDOM from 'react-dom';
export default class Nav extends Component {
constructor(props) {
super();
}
componentDidUpdate() {
this.updateBoundry();
}
componentDidMount() {
this.updateBoundry();
}
updateBoundry = () => {
const target = ReactDOM.findDOMNode(this).querySelector('.active');
const boundry = ReactDOM.findDOMNode(this).querySelector('.'+styles.boundry);
if (target) {
boundry.style.transform = `translateX(${target.offsetLeft}px)`
boundry.style.width = `${target.offsetWidth}px`
}
}
render() {
return (
<nav ref="nav" className={styles.nav}>
<span className={styles.boundry}></span>
<li className={styles.item} >
<NavLink exact className={styles.link} to='/'>Home</NavLink>
</li>
<li className={styles.item}>
<NavLink exact className={styles.link} to='/training'>Decks</NavLink>
</li>
</nav>
);
}
}
Answer the question
In order to leave comments, you need to log in
element.getBoundingClientRect() - everything you need is there.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question