Domanda

Ho problemi a ottenere elementi di menu collegati a un gestore di eventi.Ecco un finto dell'UI che mostra cambiamenti di stato nel tempo.È un menu a discesa (tramite Bootstrap), con la voce del menu Root che mostra la selezione corrente:

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

L'obiettivo finale è di modificare il contenuto della pagina in base alla selezione dell'utente.Cliccando su Bob dovrebbe innescare il handleClick, ma non è.

Come nota laterale, non sono terribilmente soddisfatto del modo in cui il componentDidMount chiama this.handleClick();, ma funziona per ora come un modo per ottenere il contenuto del menu iniziale dal server.

/** @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')
  );
});
.

Sono quasi positivo che la mia intesa nebbiosa dello scoperto JavaScript è incolpa, ma tutto ciò che ho provato finora ha fallito (incluso il tentativo di passare il gestore attraverso i puntelli).

È stato utile?

Soluzione

Il problema è che stai creando i nodi dell'oggetto utilizzando una funzione anonima e all'interno di quel this indica il window.La correzione è aggiungere .bind(this) alla funzione anonima.

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

o creare una copia di this e usa invece:

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

Altri suggerimenti

Come posso comprendere la specifica dell'attività per "Anna", "Bob", "CAL, la soluzione può essere il seguente (basato su un componente reagire ed ES6):

Basic Live Demo è qui

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>
    )
  }
}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top