2017-06-17 23 views
1

我有一个页面上的多个自定义生成下拉组件的反应。我触发列表项使用的setState点击任何地方关闭下拉反应

toggleDropdown = (id) => { 
     this.setState(prevState => ({ 
      [`dropdown${name}`]: !prevState[`dropdown${id}`] //dropdownA, dropdownB, dropdownC and so on 
     })) 
    } 

这也将触发,如果被点击下拉菜单时开开。但是,我有更多的下拉菜单,其他下拉菜单不会关闭,如果我打开下拉菜单,如何解决这个问题?我做了一个“hacky”的方式,在componentWillMount中与jquery进行混合反应,在body上绑定点击事件,检查下拉列表项是否可见,如果是,关闭它。

我的问题是,是否有避免使用jQuery的更好的做法?

+0

您可以提供app.js的例子吗? –

回答

3

我的建议是,你使用的合成事件onFocusonBlur触发开/关状态。点击该元素时将触发onFocus,并在“未聚焦”(点击外部)时触发onBlur。见docs

另外tabIndex属性是需要焦点/模糊处理非输入类型元素。

我可以推荐看看source of react-select以及他们如何处理聚焦/模糊。

下面是一个例子,你可以看到它的演示here

import React from 'react' 

class Dropdown extends React.Component { 

    constructor(props) { 
    super(props); 

    this.state = { 
     open: false 
    }; 
    } 

    toggleDropdown() { 
    this.setState({open: !this.state.open}); 
    } 

    render() { 
    return (
     <div 
     style={{border: '1px solid #CCC'}} 
     onBlur={() => this.toggleDropdown()} 
     onFocus={() => this.toggleDropdown()} 
     tabIndex='0' 
     > 
     Dropdown 
     { this.state.open && 
      <div> 
      <div>Red</div> 
      <div>Green</div> 
      <div>Blue</div> 
      </div> 
     } 
     </div> 
    ); 
    } 

} 

export default Dropdown; 
+1

辉煌的解决方案,非常感谢 –

+0

@heyhugo你知道如何让儿童元素('

Red
')也可以在不使父母最小化的情况下进行促销? –

+0

@JohnCullen使用node.contains()(浏览器DOM)API来检查父级是否包含单击的元素。你可以看看它是如何完成的:https://github.com/JedWatson/react-select/blob/master/src/Select.js#L223 – heyhugo

0

您可以使用react-onclickoutside库来抽象您的身体事件处理。您只需将自己的组件封装在onClickOutside高阶组件中,该组件在执行handleClickOutside回调时,只要点击发生在下拉菜单之外。这样,您可以在所有下拉菜单中拥有私密的“开放”状态,而且不必关心如何实现处理。

的代码可能看起来像:

import React, { Component } from 'react' 
import onClickOutside from 'react-onclickoutside' 

class Dropdown extends Component { 
    constructor() { 
     this.state = {open: false} 
    } 

    // Method automatically executed by the library. 
    handleClickOutside() { 
     this.setState({open: false}) 
    } 

    render() { ... } 
} 

export default onClickOutside(Dropdown) 
相关问题