【问题标题】:if clicked on another element remove class with react如果单击另一个元素,则使用 react 删除类
【发布时间】:2016-12-13 18:00:35
【问题描述】:

目前从 jquery / php webapp 升级以做出反应。一切进展顺利,我了解 react 等背后的概念。我找不到解决方法的唯一问题是如何根据用户单击的位置动态添加/删除类。我需要这个,因为我有一些下拉菜单会在用户点击它时触发,如果他们点击其他地方就需要隐藏。

发件人:Give a class of "selected" when clicked on another <a> then remove the class if it's the same <a>

我拿了这个例子,因为它很简单,Jquery解决问题的方法:

var h2 = $("h2 a");

h2.on("click", function() {
  if ($(this).is(".selected")) {
    $(this).removeClass("selected");
  } else {
    h2.removeClass("selected")
      .filter(this).addClass("selected")
  }
});

如何在 react(和/或 redux)中模仿相同的功能?

图片进一步说明

【问题讨论】:

    标签: css reactjs


    【解决方案1】:

    问题是,您想在点击事件上切换一些数据并相应地更改 html 元素的类名。

    “选择”类所依据的数据可能来自任何地方,来自父级或组件状态。你会做这样的事情:

    <div className={ myData ? 'selected' : '' } ></div>
    

    但是有一个更好的方法来显示类名的变化,这个库叫做类名。完成同样的事情:

    <div className={ classNames({ 'selected' : myData }) } ></div>
    

    到目前为止,我们已经了解了如何在渲染函数上显示更改。您需要做的第二件事是监听点击事件并触发函数,该函数最终将切换控制“选定”类名的数据,在我的示例中为“myData”。

    这是一个工作示例,可能有多种方法可以完成此操作。但我强烈建议使用classnames 库来切换类名。

    当另一个元素(除了我们观察到的 li 元素)被点击时移除类的解决方法可以通过点击事件监听器来解决。

    For instance : 
    
    import React, { Component }     from 'react'
    import classNames               from 'classnames'
    
    class DropDown extends Component {
      constructor(props){
        super(props)
        this.state = {
          activeSelected : ''
        }
        this.handleClick = this.handleClick.bind(this)
      }
      componentDidMount(){
        global.document.addEventListener( 'click', this.handleClick, false )
      }
      componentWillUnmount(){
        global.document.removeEventListener( 'click', this.handleClick, false )
      }
      handleClick(event){
        if( event.target.className.includes('not-changing-css-class') && 
            this.state.activeSelected !== '' 
        ) this.setState( { activeSelected : '' } )
      }
      render(){
        let { activeSelected } = this.state
        return (
          <ul>
            <li 
              className={ classNames({
                'not-changing-css-class' : true,
                'selected' : activeSelected === 'item1'
              }) } 
              onClick={ event => this.setState({ activeSelected : activeSelected === 'item1' ? '' : 'item1' }) }
            >
              Item 1
            </li>
            <li 
              className={ classNames({
                'not-changing-css-class' : true,
                'selected' : activeSelected === 'item2'
              }) } 
              onClick={ event => this.setState({ activeSelected : activeSelected === 'item2' ? '' : 'item2' }) }
            >
              Item 2
            </li>
            <li 
              className={ classNames({
                'not-changing-css-class' : true,
                'selected' : activeSelected === 'item3'
              }) } 
              onClick={ event => this.setState({ activeSelected : activeSelected === 'item3' ? '' : 'item3' }) }
            >
              Item 3
            </li>
          </ul>
        )
      }
    }
    

    【讨论】:

    • 如果用户点击其他地方(也就是不是这 3 个项目之一),这是否也会删除 selected 类?
    • 什么意思?只有当有人点击我代码中的 li 元素时,才会发生这些切换。
    • 我明白,但是如果他们点击页面上的另一个元素怎么办?下拉列表仍将包含 selected 类。他们需要手动关闭它,这是我想避免的。
    • 如果我有不止一个地方可以实现这一点,这会起作用吗?
    【解决方案2】:

    您可以在组件状态中保存所选元素的索引(或 ID,如果您使用 ID)。如果你认为这个 state 与你应用中的任何其他组件相关,你可以使用 redux store,但是从 state 开始会更简单。

    一旦你有了这个状态。通过与组件状态进行比较,您可以在 render() 函数中检查是否选择了链接。您还可以在单​​击链接时更新 selectedIndex。

    呈现链接的简单示例如下。请注意,您可以将其中的一部分提取为函数,而不是在 JSX 中使用表达式。

    ```

    allLinks.map( (link, index) => 
      <a href={link.target} className={this.state.selectedIndex === index ? 'selected' : null}/>
    )
    

    ```

    【讨论】:

    • 我不确定使用 map() 创建所有链接是否明智,因为有些链接显然可以通过 ajax 调用左右创建。
    • 不确定您的应用程序,但如果您不想使用地图,您可以继续使用data- 属性或 ID 而不是索引以保持答案中提到的状态.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    相关资源
    最近更新 更多