Javascript React onClick事件在有条件呈现时不触发

Javascript React onClick事件在有条件呈现时不触发,javascript,reactjs,Javascript,Reactjs,我正在React中构建一个searchDropdown组件。我只想在搜索字段处于活动状态时渲染下拉列表。所以我设置了一个条件来渲染下拉列表 但当有条件地呈现下拉列表时,不会触发下拉列表中的onClick事件 我的组件在下面 import React, {Component} from 'react'; import PropTypes from 'prop-types'; import {List, ListItem} from 'material-ui/List'; import {Card}

我正在React中构建一个searchDropdown组件。我只想在搜索字段处于活动状态时渲染下拉列表。所以我设置了一个条件来渲染下拉列表

但当有条件地呈现下拉列表时,不会触发下拉列表中的
onClick
事件

我的组件在下面

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {List, ListItem} from 'material-ui/List';
import {Card} from 'material-ui/Card';
import Divider from 'material-ui/Divider';
import TextField from 'material-ui/TextField';
import resources from '../../resources/resources';
import cx from 'classnames';

import './SearchDropdown.scss';

class SearchDropdown extends Component {
  constructor(props) {
    super(props);
    this.cardContainerStyle = {
      'maxHeight': '300px',
      'overflow': 'scroll',
      'border': '1px solid rgb(158, 158,158)'
    };
    this.searchFieldUnderlineStyle = {
      'borderBottom': '1px solid #ccc'
    }
    this.state = {
      dropdownStyle: {}
    };
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.isActive && this.props.isActive !== nextProps.isActive) {
      this.shouldSetBounds = true;
    } else {
      this.shouldSetBounds = false;
    }
  }



  componentDidUpdate() {
    if(this.shouldSetBounds) {
      this._setDropdownBounds();
      this.shouldSetBounds = false;
    }
  }

  componentDidMount() {
    window.addEventListener('scroll',  this._handleScroll);
  }

  componentWillUnmount() {
    window.removeEventListener('scroll',  this._handleScroll);
  }

  _handleScroll = () => {
    if (this.props.isActive) {
      this._setDropdownBounds();
    }
  }

  _setDropdownBounds() {
    const dropdownContainerOffset = this.dropdownContainer.getBoundingClientRect();
    const containerTop = dropdownContainerOffset.top;
    const containerLeft = dropdownContainerOffset.left;
    const viewportHeight = window.innerHeight;
    const viewportWidth = window.innerWidth;
    const dropdownStyle = {
      top: dropdownContainerOffset.top + dropdownContainerOffset.height,
      left: dropdownContainerOffset.left
    };

    if (containerTop > viewportHeight/2) {
      dropdownStyle.top = 'auto';
      dropdownStyle.bottom = viewportHeight - containerTop;
    }
    this.setState({ dropdownStyle });
  }

  _renderDropdown() {
    const {onSelect, datalist = []} = this.props;

      return (
        <div className="search-dropdown-wrapper" style={this.state.dropdownStyle} onClick={(event) => {alert("Outer wrapper")}}>
          <Card containerStyle={this.cardContainerStyle}>
            <div>
            {"Sample Dropdown"}
            </div>
          </Card>
        </div>
      );
  }

  _renderSearchField() {
    const {value, handleSearch} =  this.props;

    return (
      <TextField
        value={value}
        onChange={handleSearch}
        fullWidth={true}
        hintText={resources.BRAND_SEARCH}
        underlineStyle={this.searchFieldUnderlineStyle}
      />
    );
  }

  render() {
    const {isActive, onBlur} = this.props;

    return (
      <div className="search-dropdown-container field-wrapper"
        ref={dropdownContainer => this.dropdownContainer = dropdownContainer}
        onBlur={onBlur}
        >
        {this._renderSearchField()}
        {isActive && this._renderDropdown()}
      </div>
    );
  }
}

SearchDropdown.propTypes = {
  isActive: React.PropTypes.bool.isRequired,
  value: React.PropTypes.string,
  datalist: React.PropTypes.array,
  handleSearch: React.PropTypes.func.isRequired,
  onSelect: React.PropTypes.func
}

export default SearchDropdown;
import React,{Component}来自'React';
从“道具类型”导入道具类型;
从“物料ui/List”导入{List,ListItem};
从“物料界面/卡片”导入{Card};
从“物料界面/分割器”导入分割器;
从“物料界面/文本字段”导入文本字段;
从“../../resources/resources”导入资源;
从“类名称”导入cx;
导入“./SearchDropdown.scss”;
类SearchDropdown扩展组件{
建造师(道具){
超级(道具);
此.cardContainerStyle={
“最大高度”:“300px”,
“溢出”:“滚动”,
“边框”:“1px实心rgb(158158158)”
};
this.searchFieldUnderlineStyle={
“borderBottom”:“1px实心#ccc”
}
此.state={
下拉样式:{}
};
}
组件将接收道具(下一步){
if(nextProps.isActive&&this.props.isActive!==nextProps.isActive){
this.shouldSetBounds=true;
}否则{
this.shouldSetBounds=false;
}
}
componentDidUpdate(){
如果(此.shouldSetBounds){
这是。_setDropdownBounds();
this.shouldSetBounds=false;
}
}
componentDidMount(){
window.addEventListener('scroll',this.\u handleScroll);
}
组件将卸载(){
window.removeEventListener('scroll',this.\u handleScroll);
}
_handleScroll=()=>{
如果(this.props.isActive){
这是。_setDropdownBounds();
}
}
_setDropdownBounds(){
const dropdownContainerOffset=this.dropdownContainer.getBoundingClientRect();
const containerTop=dropdownContainerOffset.top;
const containerLeft=dropdownContainerOffset.left;
常量视口高度=window.innerHeight;
const viewportWidth=window.innerWidth;
常量下拉样式={
top:dropdownContainerOffset.top+dropdownContainerOffset.height,
左:dropdownContainerOffset.left
};
如果(容器顶部>视口高度/2){
dropdownStyle.top='auto';
dropdownStyle.bottom=视口高度-容器顶部;
}
this.setState({dropdownStyle});
}
_renderDropdown(){
const{onSelect,datalist=[]}=this.props;
返回(
{警报(“外部包装”)}>
{“样本下拉列表”}
);
}
_renderSearchField(){
const{value,handleSearch}=this.props;
返回(
);
}
render(){
const{isActive,onBlur}=this.props;
返回(
this.dropdownContainer=dropdownContainer}
onBlur={onBlur}
>
{this.\u renderSearchField()}
{isActive&&this.\u renderDropdown()}
);
}
}
SearchDropdown.propTypes={
isActive:React.PropTypes.bool.isRequired,
值:React.PropTypes.string,
数据列表:React.PropTypes.array,
handleSearch:需要React.PropTypes.func,
onSelect:React.PropTypes.func
}
导出默认搜索下拉列表;
在上面的代码中,
\u renderDropdown
仅在
isActive
true
时执行。当搜索字段处于活动状态时,所有样式都能完美地呈现组件。但是当呈现此组件时,使用类
搜索下拉包装的
div
上的
onClick
事件不起作用


我不确定我在哪里犯了错误。请让我知道,如果有任何适当的方法来做到这一点。谢谢。

请将此
绑定到构造函数中类中的所有方法,例如-

构造函数(道具){
this.\u handleScroll=this.\u handleScroll.bind(this)
this.\u setDropdownBounds=this.\u setDropdownBounds.bind(this)
}

供参考


    • 我终于成功了

      使用的箭头功能
      \u renderDropdown
      没有问题。问题在于
      \u renderDropdown
      的类
      搜索下拉列表容器
      附加到父div的
      onBlur
      事件。我已经从那里删除了
      onBlur
      事件,并将其添加到
      search下拉包装器
      div中。然后它开始正常工作


      我认为,
      搜索下拉列表包装器
      的位置是固定的,因此从技术上讲,它不会成为
      搜索下拉列表容器的一部分。因此
      单击
      搜索下拉包装上发生的事件
      首先触发
      搜索下拉容器的
      onBlur
      事件。因此,
      点击
      事件没有在
      搜索下拉包装上触发

      代码看起来很好,如果没有调试很难说,你能用这个问题创建一个存储库,或者把它放在webpackbin的某个地方,我可以在那里玩它吗?他对这个
      使用了一种特殊的语法
      是,您可以在类属性中使用箭头函数。但是对于
      \u setDropdownBounds
      \u renderDropdown
      ,也应该这样做,
      \u renderSearchField
      但是这些方法是在正确的上下文中调用的,因此它不是问题的根源。
      componentdiddupdate
      可以访问类
      this
      ,并且内部调用的每个函数也可以访问相同的上下文。看看这里的console.log,我可以访问组件范围。哇!谢谢。我误解了react是如何在
      react.creatClass
      中自动绑定的。您可以看到,当您将这些
      回调
      传递给
      子组件时,会出现
      未正确绑定的问题,其中
      值未绑定到正确的父组件,除非您自己绑定(通过显式绑定或