使用React在元素列表上实现“toggle类”功能

时间:2015-08-23 18:43:02

标签: javascript reactjs

我正在努力在React中实现'toggle class'功能。 我有NavSidebar组件,这是一个无序列表ul。我的NavListItem组件是列表项li

单击列表项时,我需要为单击的active提供类名li,其他列表元素应该为空类名称。

这是我到目前为止所提出的:

class NavListItem extends React.Component {
  constructor(props) {
    super(props);
    this.state = { active: false };
  }

  setActive(bool) {
    this.setState({ active: bool });
  }

  render() {
    let index = this.props.key;
    let item = this.props.item;
    return (
      <li className={this.state.active ? 'active' : ''}
          onClick={this.setActive(this.props.setActive).bind(this)} >
        <a href={'#'+item}>{item}</a>
      </li>
    );
  }
}

class NavSidebar extends React.Component {

  constructor(props) {
    super(props);
  }

  render () {

    let items = this.props.navItems.map( (item, index) => {
      return (
        <NavListItem key={index} item={item} setActive={true} />
      );
    });

    return (
        <div className="col-sm-2">
          <nav className="nav-sidebar">
            <ul className="nav">
              {items}
              <li className="nav-divider" />
              <li>
                <a href="#"><i className="glyphicon glyphicon-home"></i> Back Home</a>
              </li>
            </ul>
          </nav>
        </div>
    );
  }
}

NavSidebar.propTypes = {
  navItems: React.PropTypes.array
};

不幸的是,这不起作用,它甚至从未触及元素的className,我无法提出工作解决方案。

你能帮帮我吗?

1 个答案:

答案 0 :(得分:5)

这里没有错误信息?

onClick={this.setActive(this.props.setActive).bind(this)}

因为您绑定undefined,所以调用this.setActive(this.props.setActive)

的结果

即使你删除了绑定,它也不会起作用,因为点击处理程序将是undefined。此外,永远不应在render内修改状态。

在任何情况下,因为您想要更新多个项目(新选择的项目和旧项目),所以父项应对此负责并且应该:

  • 激活点击的项目
  • 停用所有其他人
  • 重新呈现列表

像这样(未经测试):

class NavListItem extends React.Component {
  constructor(props) {
    super(props);
  }

  setActive(bool) {
    this.props.onItemActive(this.props.item);
  }

  render() {
    let item = this.props.item;
    return (
      <li className={this.props.active ? 'active' : ''}
          onClick={this.setActive.bind(this)} >
        <a href={'#'+item}>{item}</a>
      </li>
    );
  }
}

class NavSidebar extends React.Component {

  constructor(props) {
    super(props);
    this.state = {activeItem: null};
  }

  onItemActive(item) {
    this.setState({activeItem: item};
  }

  render () {
    let self = this;
    let items = this.props.navItems.map( (item, index) => {
      return (
        <NavListItem key={index} item={item} 
                     onItemActive={self.onItemActive.bind(self)} 
                     active={item === self.state.activeItem} />
      );
    });

    return (
        <div className="col-sm-2">
          <nav className="nav-sidebar">
            <ul className="nav">
              {items}
              <li className="nav-divider" />
              <li>
                <a href="#"><i className="glyphicon glyphicon-home"></i> Back Home</a>
              </li>
            </ul>
          </nav>
        </div>
    );
  }
}

NavSidebar.propTypes = {
  navItems: React.PropTypes.array
};