代码之家  ›  专栏  ›  技术社区  ›  Hemadri Dasari

当在react中选择项时,不会调用下拉式菜单onclick

  •  1
  • Hemadri Dasari  · 技术社区  · 6 年前

    当我选择下拉项时,不会调用onlick事件处理程序。

    我正在循环生成下拉列表 componentDidMount() “显示数据类型名” onclick 在生成下拉列表时,但由于某些原因它没有被调用。知道为什么会失败吗?

    下面是我生成下拉列表的组件

    export class GenerateParams extends Component{
        constructor(props){
            super(props);
            this.state = {
                dataTypeName: "Select Type",
                rows: []
            }
        }
    
        componentDidMount(){
            let dataTypes = [];
            let content = this.state.rows.slice();    
            if(typeof this.props.apiPropertiesSuccess != 'undefined' && this.props.apiPropertiesSuccess.size > 0){
                this.props.apiPropertiesSuccess.map((type, i) => {
                    dataTypes.push(<li key={type.get('id')}><a onClick = {this.showDataTypeName(type.get('id'), type.get('name'))}> {type.get('name')} </a></li>)
                });
            }
    
    
            for(let i=0; i < this.props.params.length; i++){
                content.push(<div>
                    <div className="col-md-6">
                        <TextInput size="medium" value={this.props.params[i]} readOnly/>
                    </div>
                    <div className="col-md-6">
                        <div className="dropdown">
                            <button className="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">{this.state.dataTypeName}
                                <span className="caret"></span>
                            </button>
                            <ul className="dropdown-menu">
                                {dataTypes}
                            </ul>
                        </div>
                    </div>
                </div>)
            }
    
            this.setState({rows:content})
        }
        showDataTypeName = (id, name) => {
            console.log("id, name", id, name)
            this.props.handleDataTypes(id, name);
            this.setState({
                dataTypeName: name
            });
        }
    
        render(){
            const {params, apiPropertiesSuccess} = this.props;     
    
            return(
                <div>
                    {this.state.rows}
                </div>
            )
        }
    }
    

    注意:接受xadm的回答,因为他的解决方案是先发布的。感谢@UtkarshPramodGupta和@anshul。

    4 回复  |  直到 6 年前
        1
  •  -2
  •   xadm    6 年前

    最简单的解决方案(react docs): this.showDataTypeName = this.showDataTypeName.bind(this) 在构造函数中

    如果您喜欢使用箭头功能(自动绑定),可以使用: onClick={ () => this.showDataTypeName(type.get('id'), type.get('name')) }

    但请记住,出于性能原因,render中的绑定不是最佳的。

        2
  •  1
  •   UtkarshPramodGupta    6 年前

    你打电话给onclick的方式不对。下面是正确的代码:

    <a onClick = {this.showDataTypeName.bind(this, type.get('id'), type.get('name'))}>
    
        3
  •  0
  •   Navin Gelot    6 年前

    你必须指定 onClick 单击按钮时的事件

    <div className="dropdown">
        <button onClick={() => console.log('yeah')} className="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">{this.state.dataTypeName}
                                    <span className="caret"></span>
                                </button>
                            <ul className="dropdown-menu">
                                {dataTypes}
                            </ul>
                        </div>
    
        4
  •  0
  •   Anshul Bansal    6 年前

    您需要按如下所示编辑函数。

    showDataTypeName = (id, name) => () => {
            console.log("id, name", id, name)
            this.props.handleDataTypes(id, name);
            this.setState({
                dataTypeName: name
            });
        }
    

    编辑

    要提高性能,一个更好的方法是将click处理程序绑定到 ul 元素,并使用事件传播来处理click函数。我已经更新了代码来反映同样的情况。

    export class GenerateParams extends Component{
        constructor(props){
            super(props);
            this.state = {
                dataTypeName: "Select Type",
                rows: []
            }
        }
    
        componentDidMount(){
            let dataTypes = [];
            let content = this.state.rows.slice();    
            if(typeof this.props.apiPropertiesSuccess != 'undefined' && this.props.apiPropertiesSuccess.size > 0){
                this.props.apiPropertiesSuccess.map((type, i) => {
                    dataTypes.push(
                        <li key={type.get('id')} id={type.get('id')} name=type.get('name')>
                        {type.get('name')}
                    </li>);
                });
            }
    
    
            for(let i=0; i < this.props.params.length; i++){
                content.push(<div>
                    <div className="col-md-6">
                        <TextInput size="medium" value={this.props.params[i]} readOnly/>
                    </div>
                    <div className="col-md-6">
                        <div className="dropdown">
                            <button className="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">{this.state.dataTypeName}
                                <span className="caret"></span>
                            </button>
                            <ul className="dropdown-menu" onClick={this.showDataTypeName}>
                                {dataTypes}
                            </ul>
                        </div>
                    </div>
                </div>)
            }
    
            this.setState({rows:content})
        }
        showDataTypeName = (event) => {
            let id = event.target.id;
            let name = event.target.name;
            console.log("id, name", id, name)
            this.props.handleDataTypes(id, name);
            this.setState({
                dataTypeName: name
            });
        }
    
        render(){
            const {params, apiPropertiesSuccess} = this.props;     
    
            return(
                <div>
                    {this.state.rows}
                </div>
            )
        }
    }