I have code at the following url: https://gist.github.com/motleydev/6d5e980e4d90cc5d52fd where I am constructing a tab type setup. There's a row of tabs, a section of content and then another row of images with an alternating active state depending on which tab is "open." What I ultimately need to do is be able to get the index of the tab clicked but I can't seem to figure out a good way to do that. All I need is just the integer. Appreciate any insight. Thanks!
Asked
Active
Viewed 8,432 times
1
-
Make another component called Tab and send the Container onClick event as a property as well as the index. Then you can invoke onClick on the actual tab where you call the Container's onClick with the correct index. Its dirty, but I think it will work. – magnudae Mar 19 '15 at 11:05
-
**I believe the answer is to store the index on the HTML element, and retrieve with e.target or e.currentTarget**, not to bind the function every time the map happens – neaumusic Feb 16 '17 at 19:42
-
http://stackoverflow.com/a/20383295/1487102 – neaumusic Feb 16 '17 at 19:47
3 Answers
8
I'm not able to test this currently, but something along the lines of this. Basically send a callback and an index to each individual tab. When a tab is clicked, execute the callback with the index as parameter:
var Tab = React.createClass({
handleClick: function (event) {
event.preventDefault();
this.props.tabClicked(this.props.index);
},
render: function () {
return (
<li>
<a href="#" onClick={this.handleClick}>Tab {this.props.index}</a>
</li>
);
}
});
var Tabs = React.createClass({
handleClick: function (index) {
console.log('Tab #' + index);
},
render: function(){
var self = this;
var tabs = this.props.tabs.map(function (tab, index) {
return (
<Tab key={index} index={index} tabClicked={this.handleClick} />
)
});
return (
<nav>
<ul>
{tabs}
</ul>
</nav>
);
}
});

jdlm
- 6,327
- 5
- 29
- 49
-
-
This is the correct answer. Also you can create a wrapper to capture the event and pass it to parent along with data element. You can check this fiddle https://jsfiddle.net/parthapal33/cydubbxh/ – Partha Pal May 17 '17 at 11:40
1
It is possible to it do without creating a new component by using getAttribute() function of event.target and adding index as a custom attribute
var Tabs = React.createClass({
handleClick: function(event){
event.preventDefault();
console.log(event.target.getAttribute('index');
},
render: function(){
var self = this;
var tabs = this.props.tabs.map(function(tab,index){
var clickHandler = self.handleClick;
return (<li key={'tab'+index}><a ref={'tab'+index} index={index} href="#" onClick={clickHandler} > {tab.meta.title}</a></li>)
});
return (
<nav>
<ul>
{tabs}
</ul>
</nav>
)
}
});
You can find more information about event.target.getAttribute() at https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes#JavaScript_Access

Black
- 9,541
- 3
- 54
- 54
-1
Jorum solution works.
You can also replace:
handleClick: function(event){
event.preventDefault();
console.log(this);
},
render: function(){
var self = this;
var tabs = this.props.tabs.map(function(tab,index){
var clickHandler = self.handleClick;
return (<li key={'tab'+index}><a ref={'tab'+index} href="#" onClick={clickHandler} > {tab.meta.title}</a></li>)
});
return (
<nav>
<ul>
{tabs}
</ul>
</nav>
)
}
});
By:
handleClick: function(index){
event.preventDefault();
console.log(this);
},
render: function(){
var self = this;
var tabs = this.props.tabs.map(function(tab,index){
var clickHandler = self.handleClick.bind(null,index);
return (<li key={'tab'+index}><a ref={'tab'+index} href="#" onClick={clickHandler} > {tab.meta.title}</a></li>)
});
return (
<nav>
<ul>
{tabs}
</ul>
</nav>
)
}
});

Sebastien Lorber
- 89,644
- 67
- 288
- 419
-
so, I'm going to give you the credit because it's a functioning solution with less code, though I appreciate Jorums solution too. I was trying a "flavor" of this solution first but each time I tried passing "this" into the first param of the bind instead of the null object and it kept saying "react's doing that for you, stop doing it yourself" or something in that vein. why does it work with null object and does the event just get passed regardless? – motleydev Mar 19 '15 at 14:51
-
I had this problem too. This is because React does not want you to change the context of the method call (even if you bind to the already binded component which is a bit weird), and only binding with null does not change the context. Alternatively you can use _.partial from underscore/lodash – Sebastien Lorber Mar 19 '15 at 15:34
-
I'm trying this approach and the index passes down fine.However, "this" in my click handler is now null and I need to be able to set state in the click handler via the usual means --> this.setState({...}) because "this" is null. – eponymous23 Mar 19 '16 at 04:26