Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Button onClick triggered when init in React application

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>
    );
  }
}
like image 922
Tachun Lin Avatar asked Oct 04 '15 19:10

Tachun Lin


1 Answers

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>
    );
  }
}
like image 136
Juan Rechach Avatar answered Sep 30 '22 02:09

Juan Rechach