【问题标题】:Dynamically set a class for menu element with className使用 className 为菜单元素动态设置一个类
【发布时间】:2018-01-30 23:01:38
【问题描述】:

如果我将菜单项标记为突出显示,我将如何告诉我的渲染只填充类名(我使用的是类名)。

有两个限制:

  1. 一些菜单项是指向应用程序部分的 href/nav 链接,单击它们时必须应用我想要以支持整个组件能够检查地址的方式构建我的代码的样式它决定菜单项是否应该具有样式也取决于它。 (As-in 支持用户通过手动导航(在地址栏中输入 /item)而不是单击菜单项来“破坏”应用程序。

  2. 有些菜单项展开有些不展开,单击链接菜单项或展开下拉菜单是应用该样式的两个正当理由,请记住,在其他地方导航时展开的元素保持展开状态。

因此,这不仅仅是“如果您不是最后点击的项目,则失去样式”的情况。

更新(2017 年 8 月 23 日):

我从@taylorc93 那里得到了这个,这是一个进步:

constructor(props) {
    super(props);
    this.state = {
        selected: null;
    };
    this.setSelected = this.setSelected.bind(this);
}

setSelected(row) {
  return () => {
    this.setState({ selected: row });
  }
}

render() {
    var classes = classNames(this.props.className, {
        // if(this.selected)
        'selected': (this.props.selected === this.props.className),
    });
    return (
        <div id="menu">
          <div
            onClick={this.setSelected(1)}
            className={classNames(this.props.className, {
              'selected': this.state.selected === 1,
            })}
          >
            Dropdown 1
          </div>

          <div
            onClick={this.setSelected(1)}
            className={classNames(this.props.className, {
              'selected': this.state.selected === 1,
            })}
          >
            Menu item 2
          </div>

          <div
            onClick={this.setSelected(1)}
            className={classNames(this.props.className, {
              'selected': this.state.selected === 1,
            })}
          >
            Menu item 3
          </div>
        </div>
    );
}

thta 的问题是它没有考虑下拉行为(单击一次以选择第二次以取消选择) 所以我对它说话,这就是我所在的位置:

constructor(props) {
    super(props);
    this.state = {
        tttattta: '',
        selected: null,
        dropDownOne: false,
        dropDownTwo: false,
    };
    this.setSelected = this.setSelected.bind(this);
}

setSelected(row) {
    let tttattta = this.state.tttattta;
    let drop1 = this.state.dropDownOne;
    let drop2 = this.state.dropDownTwo;
    if (row === 1) {
        if (drop1) {
            drop1 = false;
        } else {
            drop1 = true;
        }
    } else if (row === 3) {
        if (drop2) {
            drop2 = false;
        } else {
            drop2 = true;
        }
    } else {
        tttattta = row;
    }
    return () => {
        this.setState({ selected: tttattta,
            dropDownOne: drop1,
            dropDownOne: drop2,
        });
    };
}


render() {
    var classes = classNames(this.props.className, {
        // if(this.selected)
        'selected': (this.props.selected === this.props.className),
    });
    return (
        <div id="menu">
          <div
            onClick={this.setSelected(1)}
            className={classNames(this.props.className, {
              'selected': this.state.selected === 1,
            })}
          >
            Dropdown 1
          </div>

          <div
            onClick={this.setSelected(1)}
            className={classNames(this.props.className, {
              'selected': this.state.selected === 1,
            })}
          >
            Menu item 2
          </div>

          <div
            onClick={this.setSelected(1)}
            className={classNames(this.props.className, {
              'selected': this.state.selected === 1,
            })}
          >
            Menu item 3
          </div>
        </div>
    );
}

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    问题是您在渲染函数中调用了setSelected

    <div className={classes} onClick={this.setSelcted(1)}> Menu item 1</div>
    

    你需要让setSelected返回一个可以在项目被实际点击时调用的函数:

    setSelected(row){
      return () => {
        // switch statement here
      }
    }
    

    更新:

    似乎您正在尝试找到一种更好的方式来表示所选项目,这很好:)。我建议将所选项目的 id 存储在您的状态中,而不是布尔数组。您的课程将如下所示:

    class MenuComponent extends Component {
    
    constructor(props) {
        super(props);
        this.state = {
            selected: null;
        };
        this.setSelected = this.setSelected.bind(this);
    }
    
    setSelected(row) {
      return () => {
        this.setState({ selected: row });
      }
    }
    
    render() {
        var classes = classNames(this.props.className, {
            // if(this.selected)
            'selected': (this.props.selected === this.props.className),
        });
        return (
            <div id="menu">
              <div
                onClick={this.setSelcted(<REPLACE_WITH_ROW_NUM>)}
                className={classNames(this.props.className, {
                  'selected': this.state.selected === <REPLACE_WITH_ROW_NUM>,
                })}
              >
                Menu item 1
              </div>
              { /* rest of your menu items here */ }
            </div>
        );
    }
    

    【讨论】:

    • 关于更新的答案:哇,这更像它!然而,我们完全抛弃了下拉和链接之间区分行为的概念。这种行为非常适合下拉菜单(单击一次时选择,再次单击时取消选择)对于需要单独拥有“已选择”特征的普通菜单项而言(它们不能是多个)突出显示)。
    • 还有什么想法可以区分这两者吗?也许我只是制作了两种不同的方法和两个不同的类名?一种用于下拉菜单,一种用于链接。
    • 实际上并没有想到它必须是相同的功能,但带有一个额外的参数,以便我们保留“如果选择下拉菜单则取消选择所有其他”功能。正在努力。
    • 事实证明,为每个折叠页单独设置一个功能,并为普通菜单项添加一个像您这样的额外功能是最好的解决方案。我将您标记为解决方案! :)
    猜你喜欢
    • 1970-01-01
    • 2021-12-29
    • 2020-08-20
    • 1970-01-01
    • 2016-11-26
    • 2020-10-04
    • 1970-01-01
    • 2015-06-04
    • 1970-01-01
    相关资源
    最近更新 更多