I'm trying to make a simple dropdown menu but I have some problems with onClick event on list items which are in child component, the 'handleClick' function is suppose to trigger when click on a list item, but the function is trigged twice when page loaded (because there are two lists here), and when I click on list again, it will trigger twice again, I'm sure it's a simple question but I passed few hours on it but I don't really understand what it happen here, hope someone can help me please, thx!
here is my code:
import React from 'react';
import Dropdown from './../elements/dropdown.js!jsx';
export class TestPage extends React.Component {
constructor() {
super();
this.noteLIst = [
{name: 'note', label: 'Note global'},
{name: 'digitalCulture', label: 'Digital Culture'}
];
}
handleItemClick(company) {
console.log(company);
}
render() {
return (
<div className="widget">
<Dropdown list={this.noteLIst} selected={this.noteLIst[0]} whenItemClicked={this.handleItemClick} />
</div>
);
}
}
Dropdown.js
import React from 'react';
export class Dropdown extends React.Component {
constructor() {
super();
this.state = {
listVisible: false
};
}
showMenu() {
this.setState({
listVisible: true
});
document.addEventListener("click", this.hide);
}
hide() {
this.setState({
listVisible: false
});
document.removeEventListener("click", this.hide);
}
handleClick(item) {
console.log(item); // Here will log 2 items
this.props.whenItemClicked(item);
}
render() {
let listItems = _.map(this.props.list, (list, index) => {
return (
<li key={index} className={list} onClick={this.handleClick(list)}>{list.name}</li>
);
});
return (
<div className = {"dropdown-container" + (this.state.listVisible ? " show" : "")}>
<div className = {"dropdown-display" + (this.state.listVisible ? " clicked" : "")} onClick = {this.show}>
<span>
<img className="icon-arrow-bottom" src="build/image/arrow_bottom_black.png" />
</span>
<span>
{this.props.selected.name}
</span>
</div>
<ul className="dropdown-list" >
{listItems}
</ul>
</div>
);
}
}
When you use the onClick event and you want to pass parameters to the handler method, you have to use the function bind. Thus, the handler will be triggered only when you click on the list item.
onClick={this.handleClick.bind(this, list)}
This would be your Dropdown.js:
import React from 'react';
export class Dropdown extends React.Component {
constructor() {
super();
this.state = {
listVisible: false
};
}
showMenu() {
this.setState({
listVisible: true
});
document.addEventListener("click", this.hide);
}
hide() {
this.setState({
listVisible: false
});
document.removeEventListener("click", this.hide);
}
handleClick(item) {
console.log(item); // it will be log 1 item when you click
this.props.whenItemClicked(item);
}
render() {
let listItems = _.map(this.props.list, (list, index) => {
return (
<li key={index} className={list} onClick={this.handleClick.bind(this, list)}>{list.name}</li>
);
});
return (
<div className = {"dropdown-container" + (this.state.listVisible ? " show" : "")}>
<div className = {"dropdown-display" + (this.state.listVisible ? " clicked" : "")} onClick = {this.show}>
<span>
<img className="icon-arrow-bottom" src="build/image/arrow_bottom_black.png" />
</span>
<span>
{this.props.selected.name}
</span>
</div>
<ul className="dropdown-list" >
{listItems}
</ul>
</div>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With