简体   繁体   English

React.js:点击切换类名

[英]React.js: Toggle className on click

I have a <Sidebar /> component which creates two <TabLabel /> components. 我有一个<Sidebar />组件,它创建了两个<TabLabel />组件。

I want to toggle the className is-active , if you click a tab label the class is-active should be added to the <li> element and removed on the other one. 我想切换className is-active ,如果您单击选项卡标签,则class is-active应该添加到<li>元素上,并在另一个元素上删除。

There is no error ocuring, but the function toggleClass() doesn't seem to get invoked. 没有错误发生,但是函数toggleClass()似乎没有被调用。

<Sidebar /> Component: <Sidebar />组件:

constructor() {
  super();
  this.state = {
    active: 'generator'
  }
  this.toggleClass = this.toggleClass.bind(this);
}

toggleClass() {
  this.setState({active: 'code'});
}

render() {
  return (
    <div className="sidebar">
      <ul className="tabs-list">
        <TabLabel onClick={() => this.toggleClass()} active={this.state.active} text="Generator" />
        <TabLabel onClick={() => this.toggleClass()} active={this.state.active} text="Code" />
      </ul>
    </div>
  );
}

<TabLabel /> Component: <TabLabel />组件:

render() {
  return(
    <li className={this.props.text.toLowerCase() === this.props.active ? "is-active" : null}>
      <h2>{this.props.text}</h2>
    </li>
  );
}

The onclick event will not propagate from inside TabLabel to the onClick handler. onclick事件不会从TabLabel内部TabLabelonClick处理程序。 You need to set dedicated event prop and invoke it in the TabLabel component: 您需要设置专用的事件道具并在TabLabel组件中调用它:

render() {
  const isActive = this.props.text.toLowerCase() === this.props.active.toLowerCase()

  return(
    <li onClick={() => this.props.onSelect(this.props.text)} className={isActive ? "is-active" : null}>
      <h2>{this.props.text}</h2> 
    </li>
  );
}

And in Sidebar: 在补充工具栏中:

toggleClass(active) {
  this.setState({active});
}

render() {
  return (
    <div className="sidebar">
      <ul className="tabs-list">
        <TabLabel onSelect={this.toggleClass} active={this.state.active} text="Generator" />
        <TabLabel onSelect={this.toggleClass} active={this.state.active} text="Code" />
      </ul>
    </div>
  );
}

Why don't you keep TabLabel as dumb as possible and only propagate props to it? 为什么不将TabLabel保持尽可能的哑巴,而只向其传播道具呢?

Also, TabLabel needs to dispatch click changes so Sidebar knows which Tab has been selected. 另外, TabLabel需要调度点击更改,以便Sidebar知道已选择了哪个选项卡。

Testability gets easier and you can even improve TabLabel rendering on Sidebar (such as using an array of tabs). 可测试性变得更加容易,您甚至可以改善Sidebar上的TabLabel呈现(例如使用选项卡数组)。

 class Sidebar extends React.Component { constructor() { super() this.state = { active: 'generator', } } toggleClass(tab) { this.setState({ active: tab, }) } render() { const { active } = this.state return ( <div> <div className="sidebar"> <ul className="tabs-list"> <TabLabel onClick={this.toggleClass.bind(this, 'generator')} active={active === 'generator'} text="Generator" /> <TabLabel onClick={this.toggleClass.bind(this, 'code')} active={active === 'code'} text="Code" /> </ul> </div> </div> ) } } const TabLabel = ({ active, text, onClick }) => <li onClick={onClick} className={active ? 'is-active' : null}> <h2>{text}</h2> </li> ReactDOM.render( <Sidebar />, document.getElementById('root') ) 
 ul { list-style-type: none; margin: 0; padding: 0; } li.is-active { background-color: red; color: white; } 
 <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="root"></div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM