在子组件中调用check函数

时间:2017-08-17 06:14:08

标签: javascript reactjs ecmascript-6

我正在尝试使用自定义子组件进行自定义下拉列表。在子自定义组件中,有一个onChange事件。

现在的问题是每当我触发onChange(对于复选框)时,下拉列表就会关闭。

https://codesandbox.io/s/lr677jv7l7

部分代码

render() {

    const { className, onOpen, children } = this.props
    const { openItems, selectedItem } = this.state

    return (
      <div className={classnames('customDropdown', className)}>
        <div tabIndex="1"
          onBlur={() => { this.setState({ openItems: false }) }}
          onFocus={() => { this.setState({ openItems: true }); onOpen && onOpen() }}>
          <button className="btn">
            {selectedItem}
          </button>

          <div className={classnames('items', { 'show': openItems === true, 'hide': openItems === false })}>
            {children && children}
          </div>
        </div>
      </div>
    )
  }

1 个答案:

答案 0 :(得分:0)

你需要摆脱以下几行: onBlur={() => { this.setState({ openItems: false }) }} 它基本上表示当你的div包裹按钮失去焦点时(例如,当你点击复选框时)它应该将state.openItems变量设置为false,因此它会关闭下拉列表。

修改 在这里查看工作示例:https://codesandbox.io/s/jnq2rqwr53

基本上使用onClick而非模糊,然后您将click事件添加到文档中,因此只要用户点击文档中的任何位置,它就会调用您的hide方法并关闭模式。这样选中的复选框就会被选中,但是如果你想在选择后下拉以保持打开状态,你需要以某种方式告诉hide函数如果用户点击复选框就不会执行。我在hide方法的开头使用了id和简单的条件保护来完成它。

代码如下所示:

<强> Hello.js

import React, { Component } from 'react';
import classnames from 'classnames'

export default class CustomDropdown extends Component {


  constructor() {
    super()

    this.state = {
      openItems: false,
      selectedItem: 'Please select'
    }

    this.show = this.show.bind(this);
    this.hide = this.hide.bind(this);
  }

  show() {
    this.setState({openItems: true});
    document.addEventListener("click", this.hide);
  }

  hide(e) {
    if (e.target.id === "1" || e.target.id === "2") {
      return false;
    }

    this.setState({openItems: false});
    document.removeEventListener("click", this.hide);
  }

  render() {

    const { className, onOpen, children } = this.props
    const { openItems, selectedItem } = this.state

    return (
      <div className={classnames('customDropdown', className)}>
        <div tabIndex="1">
          <button className="btn" onClick={this.show}>
            {selectedItem}
          </button>

          <div className={classnames('items', { 'show': openItems === true, 'hide': openItems === false })}>
            {children && children}
          </div>
        </div>
      </div>
    )
  }
}

<强> index.js

import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './styles.css';

const styles = {
  fontFamily: 'sans-serif',
  textAlign: 'center'
}; 

class App extends Component {
  constructor() {
    super()
  }

  changeCheckbox = () => {
    console.log('something')
  } 

  render(){
    return(
      <div style={ styles }>
        <Hello>
          <div>
            my checkbox 1
              <input type="checkbox" onChange={this.changeCheckbox} id="1" />
          </div>

          <div>
            my checkbox 2
              <input type="checkbox" onChange={this.changeCheckbox} id="2" />
          </div>
        </Hello>
      </div>
    )
  }
}

render(<App />, document.getElementById('root'));