Есть компонент навигации, в данный момент он выглядит вот так:
spoilerimport 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>
);
}
}
Если кратко: я пытаюсь сделать перемещающийся элемент, который будет находится под активной ссылкой.
Как видно, при вызове ref-callback'a я проверяю содержит ли li активный линк и пытаюсь получить некоторые свойства с этого линка, а потом вызываю setState чтобы вызвать рендеринг и соответственно перемещение элемента boundry, однако проблема в том, что
clientWidth
возвращает 0, а
offsetLeft
непонятно откуда взявшиеся 32. Те же результаты я получаю при попытке выбрать эти элементы обычными селекторами в
componentDidMount
хуке, в остальных хуках и консоле элементы возвращают правильные значения.
вот, здесь при апдейте компонента все посчитается верно, а при маунтинге - нет(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>
);
}
}
Использую stylus-loader, css-modules, postcss, если это важно.