[英]How to update classNames in React properly?
向下滾動時,我添加和刪除了某些類。 我想在向上滾動時恢復課程。 如何僅使用 ReactJS 來完成?
我已經使用事件偵聽器來更改類。
主要概念是導航欄的內容應該顯示在中心,當我們向下滾動時,顯示在div中的網站名稱應該顯示在導航欄上,放置在中間的內容應該向左移動並且顯示網站名稱的 div 應該消失。 當我們向上滾動到帶有網站名稱的 div 時,一切都應該恢復到向下滾動之前的狀態。
import React, { Component } from 'react';
import '../Styles/Navbar.css';
export class Navbar extends Component {
handleScrollToElement(event) {
let linkPosition = document.querySelector('.collapse');
let brandName = document.querySelector('.navbar-brand');
if (window.pageYOffset > 250){
linkPosition.classList.remove('justify-content-center');
linkPosition.classList.add('justify-content-end');
brandName.classList.remove('invisible');
brandName.classList.add('visible');
}
}
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 invisible' 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 justify-content-center' 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;
使用 React.js 時,應盡量避免直接操作 DOM。 如果您確實需要對 DOM 的引用,則應改用ref 。
我會設置classNames
為linkPosition
和brandName
在狀態constructor
和更新它們handleScrollToElement
。
每當更改這些state
變量時,將調用render
函數並更新視圖。
由於scroll
事件在短時間內觸發了很多,我也擔心性能問題。 所以我在代碼中添加了shouldComponentUpdate以防止重新渲染未更改的視圖。
您也可以考慮對要調用的滾動事件處理函數進行 debounce,以減少調用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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.