簡體   English   中英

如何正確更新 React 中的 classNames?

[英]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

我會設置classNameslinkPositionbrandName在狀態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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM