React.js:点击

时间:2017-10-30 12:43:06

标签: javascript reactjs jsx

我有一个<Sidebar />组件,可以创建两个<TabLabel />组件。

我想切换className is-active,如果您点击标签标签,则应将类is-active添加到<li>元素并将其移除到另一个元素上。

没有出现错误,但函数toggleClass()似乎没有被调用。

<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 />组件:

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

2 个答案:

答案 0 :(得分:1)

onclick事件不会从TabLabel内部传播到onClick处理程序。您需要设置专用事件道具并在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>
  );
}

在补充工具栏中:

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>
  );
}

答案 1 :(得分:1)

为什么不让TabLabel尽可能愚蠢,只传播道具呢?

此外,TabLabel需要发送点击更改,以便Sidebar知道选择了哪个标签。

可测试性变得更容易,您甚至可以改进TabLabel上的Sidebar呈现(例如使用标签数组)。

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>