0
export default React.createClass({
displayName: 'Test',

getInitialState() {
    return {
        activeItem: 0,
    };
},

onItemClick(item) {
    this.setState({
        activeItem: item
    });
},

isActive(item) {
    return item === this.state.activeItem;
},

render() {
    var circle = {
        'one': {
            items: []
        }
    };

    ['one'].forEach((k, i) => {
        for (var j = 1; j <= 3; j++) {
            var itemNo = (i * 10 + j);
            var itemClasses = c('item', 'item-' + itemNo, {
                'selected': this.isActive(itemNo)
            });

            var item = React.DOM.div({
                key: "item" + itemNo,
                className: itemClasses,
                onClick: () => this.onItemClick(itemNo)
            }, itemNo);
            circle[k].items.push(item);
        }
    });


    return ( 
      <div>{circle.one.items}</div>
    );
}
});

The circle.one.items array is being populated by dynamically generated divs and should contain:

<div class="item item-1">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>

No matter what div I click on, only the 3rd one gets selected because itemNo last value is 3.

Look at: onClick: () => this.onItemClick(itemNo). This is wrong. How can I pass the ID of the div I'm clicking to onItemClick()?

apopa
  • 170
  • 9

2 Answers2

1

You are having a closure issue, by the way, a quick fix is to change the forstatement with a function iteration:

var circle = {
  'one': {
    items: [1, 2, 3].map((item, index, array) => React.DOM.div({
      onclick: () => console.log('clicked at', index, item);
    }))
  }
};
Hitmands
  • 13,491
  • 4
  • 34
  • 69
-1

After reading JavaScript closure inside loops – simple practical example, the simplest fix is to use let. I just changed var itemNo = (i * 10 + j); with let itemNo = (i * 10 + j);.

Community
  • 1
  • 1
apopa
  • 170
  • 9
  • `let` has no effect in your case, your bug depends on the `asyc` execution of your `onClick` callback... when it will be fired the value of `itemNo` is always the value of the last iteration... Using a function iteration you can keep the current value across these callbacks. – Hitmands Jul 14 '16 at 14:39
  • Well it seems that it does have effect. Thank you. – apopa Jul 14 '16 at 17:51