【问题标题】:Modify className when element is clicked in React在 React 中单击元素时修改 className
【发布时间】:2018-11-21 10:06:09
【问题描述】:

我在 ReactJS 中创建了一个菜单栏,它具有一些基本的路由功能。组件的 JSX 如下:

class TopBar extends Component {
  state = {
    menus: [{id:0,menu:"Home"}, {id:1,menu:"Contact"}, {id:2,menu:"About"}]
  }
  addClass = e => {
    console.log("Addclass "+ e.target);
  }
  render() {
    return (
      <Router>
                <div>  
                    <nav class="navbar navbar-expand-lg">
                      <div class="row">
                        <div class="col-sm-12">
                          <div class="collapse navbar-collapse">
                            <ul class="navbar-nav mr-auto">
                              {this.state.menus.map((menu,index) =>
                                    <li className="nav-item ng-star-inserted">
                                      <a className={`nav-link ${'active'}`} id={"sample"+ menu.id} onClick={this.addClass} > 
                                        <Link to={menu.menu}> {menu.menu} </Link>
                                      </a>
                                    </li>
                                )}
                            </ul>
                          </div>
                        </div>
                      </div>
                    </nav>

          <Route path="/home" exact component={
            Home
          } />
          <Route path="/contact" exact component={
           Contact
          } />
          <Route path="/about" exact component={
            About
          } />
        </div>
      </Router>
    );
  }
}

CSS:

.navbar .nav-link.active {
    border-bottom: 3px solid #fdd92d;
}

当我单击特定菜单(主页/联系人/关于)时,我希望将 active 类附加到该特定菜单。我添加了onClick 事件并尝试将id 属性传递给它。
id 在调试器中是空白的。

单击菜单后如何添加active className?

【问题讨论】:

  • 您可以使用NavLink 已经为router 提供了activeClass
  • @Dkouk 是的,但是有没有办法在不使用NavLink 的情况下做到这一点?
  • 是的,但您需要使用本地状态并将其与菜单循环的索引联系起来。例如onClick={() =&gt; this.setState({active: index})} className={this.state.active === index ? 'nav-link active' : 'nav-link'}
  • 感谢@DimitarChristoff

标签: javascript reactjs


【解决方案1】:

要使其以您的方式工作,您必须为每个菜单对象存储isActive 键。你的addClass() 函数应该是这样的:

addClass = e => {
  this.setState({
    menus: this.state.menus.map(menu => ({
      ...menu,
      isActive: e.target.id == menu.id
    }))
  })
}

每次调用 addClass 时,我们都会遍历每个菜单对象,如果菜单的 id 与用户点击的 ID 匹配,我们给它isActive: true,否则我们将它设置为 false。当然,我们使用.map 来返回一组新菜单,因为我们不能直接改变this.state.menus

然后我们可以通过检查菜单的isActive 键来检查菜单是否处于活动状态:

{
  this.state.menus.map(menu =>
    <a
      className={`nav ${menu.isActive ? 'active' : ''}`}
      id={menu.id}
      onClick={this.addClass}
    >
      {menu.menu}
    </a>
  )
}

为您构建这个有效的 sn-p:

class Hello extends React.Component {
  state = {
    menus: [{id:0,menu:"Home"}, {id:1,menu:"Contact"}, {id:2,menu:"About"}]
  }

  addClass = e => {
    this.setState({
      menus: this.state.menus.map(menu => ({
        ...menu,
        isActive: e.target.id == menu.id
      }))
    })
  }

  render() {
    return (
      <div>
        {
          this.state.menus.map(menu =>
            <a
              style={{color: menu.isActive ? 'red' : 'black'}}
              className={`nav ${menu.isActive ? 'active' : ''}`}
              id={menu.id}
              onClick={this.addClass}
            >
              {menu.menu}
            </a>
          )
        }
      </div>
    )
  }
}

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
</div>

【讨论】:

    【解决方案2】:

    你最好改用 react-router-dom 的 NavLink 东西。

    <NavLink to={menu.menu} activeClassName='active' className='nav-link'>
      {menu.menu}
    </NavLink>
    

    https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/NavLink.md

    【讨论】:

      【解决方案3】:

      以下是供您参考的示例

      import * as React from "react";
      
      import { NavLink } from "react-router-dom";
      import  styles from "./NavigationMenu.css";
      
       function NavigationMenu() {
          return (
            <React.Fragment>
             <ul className={styles.nav}>
               <li>
                <NavLink to="/home" activeClassName={styles.active}>
                   Home
                </NavLink>
              </li>
              <li>
               <NavLink to="/contacts" activeClassName={styles.active}>
                  Contacts
               </NavLink>
              </li>
             <li>
               <NavLink to="/about" activeClassName={styles.active}>
                 About
               </NavLink>
              </li>
            </ul>
         </React.Fragment>
        );
      }
      
      export default NavigationMenu;
      

      只需在 css 文件中添加 .active 类,或者如果您想重构它,您可以按如下方式创建 NavigationItem 组件

      import React from 'react';
      import { NavLink } from 'react-router-dom';
      
      import classes from './NavigationItem.css';
      
      const navigationItem = ( props ) => (
         <li className={classes.NavigationItem}>
          <NavLink 
              to={props.link}
              exact={props.exact}
              activeClassName={classes.active}>{props.children}</NavLink>
        </li>
      );
      
      export default navigationItem;
      

      &lt;NavLink&gt; 将自动将活动类添加到当前活动链接或页面

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-25
        • 1970-01-01
        • 2021-12-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多