Javascript React onClick事件在有条件呈现时不触发
我正在React中构建一个searchDropdown组件。我只想在搜索字段处于活动状态时渲染下拉列表。所以我设置了一个条件来渲染下拉列表 但当有条件地呈现下拉列表时,不会触发下拉列表中的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}
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
中自动绑定的。您可以看到,当您将这些回调
传递给子组件时,会出现此
未正确绑定的问题,其中此
值未绑定到正确的父组件,除非您自己绑定(通过显式绑定或