简体   繁体   中英

ES6/React Second item binding fails

I have a few components here. The parent component (Dropdown) has two sub components, each with a click event that's fired within Dropdown. I have no problems with the first click event (handleClick), but the binding seems to fail for the second click event (handleItemClick)

Error:

Dropdown.js:57 Uncaught TypeError: Cannot read property 'handleItemClick' of undefined

Parent component (Dropdown):

export class Dropdown extends Component {
  constructor(props) {
    super(props);
    this.state = { open: false };

    this.handleClick = this.handleClick.bind(this);
    this.handleItemClick = this.handleItemClick.bind(this);
  }
  handleClick() {
    this.setState({ open: !this.state.open });
  }
  handleItemClick() {
    console.log("anything");
  }
  render() {
    let list = this.props.items.map(function(item) {
      return <ListItem item={item} key={item} whenItemClicked={this.handleItemClick}/>
    });
    return (
      <div className="dropdown">
        <Button
          className="btn-default"
          title={this.props.title}
          subTitleClassName="caret"
          whenClicked={this.handleClick} />
        <ul className={"dropdown-menu " + (this.state.open ? "show" : "")}>
          {list}
        </ul>
      </div>
    );
  }
}

Child component (ListItem), this item's corresponding click event is the one failing to bind.

export class ListItem extends Component {
  render() {
    return (
      <li><a onClick={this.props.whenItemClicked}>{this.props.item}</a></li>
    );
  }
}

Second Child component, this item's corresponding click event works

export class Button extends Component {
  render() {
    return (
      <button onClick={this.props.whenClicked} className={"btn " + this.props.className} type="button">
        {this.props.title} <span className={this.props.subTitleClassName}>{this.props.subTitle}</span>
      </button>
    );
  }
}

This is probably something obvious that I'm overlooking. Any help would be greatly appreciated!

map will bind this to the function caller, which is the array. this inside map written with function () {} is the array not the component.

Use an arrow function instead, which will retain the 'lexical' this , the surrounding this , which is your component.

let list = this.props.items.map(item => { 
  return <ListItem whenItemClicked={this.handleItemClick}/>
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM