简体   繁体   English

在子组件中调用检查功能

[英]check function is called in child component

I am trying to make a custom dropdown but with custom children component. 我正在尝试创建一个自定义下拉列表,但带有自定义子组件。 Within the children custom component, there's an onChange event. 在子级自定义组件中,有一个onChange事件。

The problem now is whenever I trigger the onChange which is for the checkbox, the dropdown is closed. 现在的问题是,每当我触发用于复选框的onChange时,下拉列表都将关闭。

https://codesandbox.io/s/lr677jv7l7 https://codesandbox.io/s/lr677jv7l7

Partial code 部分代码

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>
    )
  }

You need to get rid of following line: onBlur={() => { this.setState({ openItems: false }) }} It basically says that when your div wrapping the button loses focus (eg when you click the checkbox) it should set the state.openItems variable to false and therefore it closes the dropdown. 您需要删除以下行: onBlur={() => { this.setState({ openItems: false }) }}基本上是说,当div包装按钮失去焦点时(例如,单击复选框时),应该将state.openItems变量设置为false ,因此它将关闭下拉列表。

Edit: Check out working example here: https://codesandbox.io/s/jnq2rqwr53 . 编辑:在此处查看工作示例: https : //codesandbox.io/s/jnq2rqwr53

Basically use onClick instead of blur and then you add click event to your document, so anytime user clicks anywhere on the document it calls your hide method and closes the modal. 基本上使用onClick而不是模糊,然后将click事件添加到文档中,因此,只要用户在文档上的任何位置单击,它就会调用您的hide方法并关闭模式。 This way the selected checkbox gets checked, but if you want to dropdown to stay open after the selection you'll need to somehow tell the hide function not to execute if user clicked on the checkbox. 这样,选中的复选框将被选中,但是如果要在选择后下拉菜单保持打开状态,则需要以某种方式告知hide功能,如果用户单击该复选框,则hide功能将不执行。 I did it using ids and simple condition guard at the beginning of the hide method. hide方法的开头,我使用ID和简单的条件防护来做到这一点。

Code looks like this: 代码如下:

Hello.js 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 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'));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM