2

I have icons I am mapping from a json table:

<ul className="major-icons">{ icons.map(function(i){
                            return <li key={i.id}><span className={i.class} id={i.id} data-id={i.data} onClick={this.onClick} onMouseOver={this.onHover}></span></li>

                                }) }

                            </ul>

var icons = [

    { data: '0', id: 'p0', class: 'icon style1 major fa-code'},
    { data: '1', id: 'p1', class: 'icon style2 major fa-bolt'},
    { data: '2', id: 'p2', class: 'icon style3 major fa-camera-retro'},
    { data: '3', id: 'p3', class: 'icon style4 major fa-cog'},
    { data: '4', id: 'sochi', class: 'icon style5 major fa-desktop'},
    { data: '5', id: 'decision_trees', class: 'icon style6 major fa-calendar'},

];

I have an event handler:

getInitialState: function() {
    return { project_id: 0};
},

onClick: function(event) {
    this.setState({ project_id: event.currentTarget.dataset.id });
    console.log("hello");
},

Unfortunately, even clicking these span icons, nothing is happening (not even the console.log). What can I do?

user1072337
  • 12,615
  • 37
  • 116
  • 195

1 Answers1

2

You have a problem with the scope of this inside your map function. The quickest way to fix your code is to preserve the scope of this. To make sure that this refers to your Component you can 1) pass this as a second argument to map, 2) use an arrow function; or 3) use the bind method. Here is a demo: http://codepen.io/PiotrBerebecki/pen/jraLWZ

I would however review this answer: https://stackoverflow.com/a/38908620/4186037 and consider refactoring the code so that we don't create a copy of the click handler for each item in the array on each re-render.

  1. Pass thisto map method

          <ul className="major-icons">{ icons.map(function(i) {
              return (
                <li key={i.id}>
                      <span className={i.class}
                            id={i.id}
                            data-id={i.data} 
                            onClick={this.onClick} 
                            onMouseOver={this.onHover}>
                        Some text
                      </span>
                </li>
              );
            }, this) }
    -----------^^^^
          </ul>
    
  2. Arrow function

          <ul className="major-icons">{ icons.map((i) => {
    --------------------------------------------------^^
            return (
                <li key={i.id}>
                      <span className={i.class}
                            id={i.id}
                            data-id={i.data} 
                            onClick={this.onClick} 
                            onMouseOver={this.onHover}>
                      </span>
                </li>
              );
            }) }
          </ul>
    
  3. Bind method

          <ul className="major-icons">{ icons.map(function(i) {
            return (
                <li key={i.id}>
                      <span className={i.class}
                            id={i.id}
                            data-id={i.data} 
                            onClick={this.onClick} 
                            onMouseOver={this.onHover}>
                      </span>
                </li>
              );
            }.bind(this)) }
    ---------^^^^^^^^^^
          </ul>
    
Community
  • 1
  • 1
Piotr Berebecki
  • 7,428
  • 4
  • 33
  • 42