Когда вы используете React. js, вам следует максимально избегать прямых манипуляций с DOM. Если вам действительно нужна ссылка на DOM, вы должны использовать ref .
Я бы установил classNames
для linkPosition
и brandName
как состояние в constructor
и обновил бы их в handleScrollToElement
.
Всякий раз, когда эти переменные state
изменяются, вызывается функция render
, которая обновляет представление.
Поскольку событие scroll
часто срабатывает в Некоторое время я беспокоился и о производительности. Поэтому я добавил в код shouldComponentUpdate , чтобы предотвратить повторную визуализацию неизмененного представления.
Можно также отменить вызов обработчика события прокрутки, вызываемого для уменьшения количества вызовов setState
.
import React, { Component } from 'react';
import '../Styles/Navbar.css';
export class Navbar extends Component {
constructor(props) {
super(props);
this.state = {
linkPositionClassName: 'justify-content-center',
brandNameClassName: 'invisible',
};
}
handleScrollToElement(event) {
if (window.pageYOffset > 250){
this.setState({
linkPositionClassName: 'justify-content-end',
brandNameClassName: 'visible',
});
} else {
this.setState({
linkPositionClassName: 'justify-content-center',
brandNameClassName: 'invisible',
});
}
}
shouldComponentUpdate(nextProps, nextState) {
const { linkPositionClassName, brandNameClassName } = this.state;
// component needs to re-render only when at least one of the state changes
return nextState.linkPositionClassName !== linkPositionClassName || nextState.brandNameClassName !== brandNameClassName;
}
componentDidMount() {
window.addEventListener('scroll', this.handleScrollToElement);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScrollToElement);
}
render() {
return (
<div>
<nav className='navbar navbar-expand-sm bg-dark navbar-dark fixed-top'>
<a className=`navbar-brand ${this.state.brandNameClassName}` href='#'>Website Name</a>
<button className='navbar-toggler' type='button' data-toggle='collapse' data-target='#navbarSupportedContent' aria-controls='navbarSupportedContent' aria-expanded='false' aria-label='Toggle navigation'>
<span className='navbar-toggler-icon'></span>
</button>
<div className=`collapse navbar-collapse ${this.state.linkPositionClassName}` id='navbarSupportedContent'>
<ul className='navbar-nav'>
<li className='nav-item active'>
<a className='nav-link' href='#'>Home</a>
</li>
<li className='nav-item'>
<a className='nav-link' href='#'>Item 2</a>
</li>
<li className='nav-item'>
<a className='nav-link' href='#'>About Us</a>
</li>
<li className='nav-item'>
<a className='nav-link' href='#'>Contact</a>
</li>
</ul>
</div>
</nav>
<div className='container-fluid hpage'>
<div className='inner'>
<h1 className='htext' >WEBSITE TITLE</h1>
</div>
</div>
</div>
)
}
}
export default Navbar;