Frage

Ich habe Probleme, Menüelemente mit einem Event-Handler zu verbinden.Hier ist eine Nachbildung der Benutzeroberfläche, die Zustandsänderungen im Laufe der Zeit zeigt.Es handelt sich um ein Dropdown-Menü (über Bootstrap), wobei im Stammmenüelement die aktuelle Auswahl angezeigt wird:

[ANN]<click  ...  [ANN]             ...    [BOB]<click  ...  [BOB]  
                    [Ann]                                      [Ann]
                    [Bob]<click + ajax                         [Bob]
                    [Cal]                                      [Cal]

Das Endziel besteht darin, den Seiteninhalt asynchron basierend auf der Auswahl des Benutzers zu ändern.Ein Klick auf Bob sollte das auslösen handleClick, aber es ist nicht.

Nebenbei bemerkt, ich bin nicht besonders zufrieden mit der Art und Weise, wie „componentDidMount“ aufruft this.handleClick();, aber es funktioniert vorerst als Möglichkeit, erste Menüinhalte vom Server abzurufen.

/** @jsx React.DOM */

var CurrentSelection = React.createClass({
  componentDidMount: function() {
    this.handleClick();
  },

  handleClick: function(event) {
    alert('clicked');
    // Ajax details ommitted since we never get here via onClick
  },
  getInitialState: function() {
    return {title: "Loading items...", items: []};
  },
  render: function() {
    var itemNodes = this.state.items.map(function (item) {
      return <li key={item}><a href='#' onClick={this.handleClick}>{item}</a></li>;
    });

    return <ul className='nav'>
      <li className='dropdown'>
        <a href='#' className='dropdown-toggle' data-toggle='dropdown'>{this.state.title}</a>
        <ul className='dropdown-menu'>{itemNodes}</ul>
      </li>
    </ul>;
  }
});


$(document).ready(function() {
  React.renderComponent(
    CurrentSelection(),
    document.getElementById('item-selection')
  );
});

Ich bin mir fast sicher, dass mein unklares Verständnis des Javascript-Scopings daran schuld ist, aber alles, was ich bisher versucht habe, ist fehlgeschlagen (einschließlich des Versuchs, den Handler durch Requisiten weiterzugeben).

War es hilfreich?

Lösung

Das Problem besteht darin, dass Sie die Elementknoten mithilfe einer anonymen Funktion erstellen, und zwar innerhalb dieser this Bedeutet die window.Die Lösung besteht darin, hinzuzufügen .bind(this) zur anonymen Funktion.

var itemNodes = this.state.items.map(function (item) {
  return <li key={item}><a href='#' onClick={this.handleClick}>{item}</a></li>;
}.bind(this));

Oder erstellen Sie eine Kopie von this und verwenden Sie stattdessen Folgendes:

var _this = this, itemNodes = this.state.items.map(function (item) {
  return <li key={item}><a href='#' onClick={_this.handleClick}>{item}</a></li>;
})

Andere Tipps

Da ich die Spezifikation der Aufgabe für „Anna“, „Bob“, „Cal“ nachvollziehen kann, kann die Lösung wie folgt aussehen (basierend auf einer React-Komponente und ES6):

Die grundlegende Live-Demo finden Sie hier

import React, { Component } from "react"

export default class CurrentSelection extends Component {
  constructor() {
    super()
    this.state = {
      index: 0
    }
    this.list = ["Anna", "Bob", "Cal"]
  }

  listLi = list => {
    return list.map((item, index) => (
      <li key={index}>
        <a
          name={item}
          href="#"
          onClick={e => this.onEvent(e, index)}
        >
          {item}
        </a>
      </li>
    ))
  }

  onEvent = (e, index) => {
    console.info("CurrentSelection->onEvent()", { [e.target.name]: index })
    this.setState({ index })
  }

  getCurrentSelection = () => {
    const { index } = this.state
    return this.list[index]
  }

  render() {
    return (
      <div>
        <ul>{this.listLi(this.list)}</ul>
        <div>{this.getCurrentSelection()}</div>
      </div>
    )
  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top