I am kind-of new to react and having trouble getting value of a radio button generated from a loop. I have a fiddle set-up at: /.
The example has two type of radio buttons. One group is generated using loop and the other one without loop. The one without loop works (logs the value of the button) but the ones created with the loop doesn't work when I try to console log the value of the radio button.
Thank you in advance.
var Inputs = React.createClass({
getInitialState: function(){
return {
radios: {
a: { radio: 'Radio Loop A' },
b: { radio: 'Radio Loop B' },
c: { radio: 'Radio Loop C' }
},
radioNoLoop: 'Radio No Loop'
}
},
selectHandlerLoop: function(e){
console.log(e.target.value);
},
selectHandle: function(e){
console.log(e.target.value);
},
render: function() {
var radios = this.state.radios;
var r = this;
return(
<div>
{/* Creating radio buttons using Array */}
{Object.keys(radios).map(function(key,r) {
return (
<div key={key}>
<label forHTML={key}>
<input type="radio" name="loopTest" value={radios[key].radio} id={key} nChange={r.selectHandlerLoop} /> {radios[key].radio}
</label>
</div>
);
})}
<hr />
{/* Radio button no array loop */}
<label forHTML="noLoop">
<input type="radio" id="noLoop" value="noLoop" onChange={this.selectHandle}/> {this.state.radioNoLoop}
</label>
</div>
);
}
});
React.render(<Inputs />, document.getElementById('container'));
I am kind-of new to react and having trouble getting value of a radio button generated from a loop. I have a fiddle set-up at: https://jsfiddle/rexonms/zrax0zfa/.
The example has two type of radio buttons. One group is generated using loop and the other one without loop. The one without loop works (logs the value of the button) but the ones created with the loop doesn't work when I try to console log the value of the radio button.
Thank you in advance.
var Inputs = React.createClass({
getInitialState: function(){
return {
radios: {
a: { radio: 'Radio Loop A' },
b: { radio: 'Radio Loop B' },
c: { radio: 'Radio Loop C' }
},
radioNoLoop: 'Radio No Loop'
}
},
selectHandlerLoop: function(e){
console.log(e.target.value);
},
selectHandle: function(e){
console.log(e.target.value);
},
render: function() {
var radios = this.state.radios;
var r = this;
return(
<div>
{/* Creating radio buttons using Array */}
{Object.keys(radios).map(function(key,r) {
return (
<div key={key}>
<label forHTML={key}>
<input type="radio" name="loopTest" value={radios[key].radio} id={key} nChange={r.selectHandlerLoop} /> {radios[key].radio}
</label>
</div>
);
})}
<hr />
{/* Radio button no array loop */}
<label forHTML="noLoop">
<input type="radio" id="noLoop" value="noLoop" onChange={this.selectHandle}/> {this.state.radioNoLoop}
</label>
</div>
);
}
});
React.render(<Inputs />, document.getElementById('container'));
Share
Improve this question
edited May 22, 2015 at 20:12
Jonny Buchanan
62.8k17 gold badges145 silver badges150 bronze badges
asked May 22, 2015 at 16:39
rexrex
1,0235 gold badges30 silver badges48 bronze badges
1
- What exactly is not working? Please explain the issue. – Felix Kling Commented May 22, 2015 at 16:43
2 Answers
Reset to default 7javascript map actually has functionality for what you're trying to do. you pass this
to the second argument of map (after the callback):
{Object.keys(radios).map(function(key) {
return (
<div key={key}>
<label forHTML={key}>
<input type="radio" name="loopTest" value={radios[key].radio} id={key} onChange={this.selectHandlerLoop} /> {radios[key].radio}
</label>
</div>
);
}, this)}
Your problem has nothing to do with React. You seem to have a misunderstanding of how functions / closures work.
Lets look at that part:
Object.keys(radios).map(function(key,r) { ... });
This declares a function expecting two arguments, key
and r
, and passes it to .map
. .map
will call the function and provide the corresponding arguments.
If you look at the .map
documentation you can see that .map
passes three arguments to the callback:
callback
Function that produces an element of the new Array, taking three arguments:
currentValue
: The current element being processed in the array.index
: The index of the current element being processed in the array.array
: The array map was called upon.
So what will the value of r
be? It will be the index of the current element.
The parameter r
has nothing to do with the variable r
you declared with
var r = this;
If you want r
inside the callback to refer to that variable, remove it from the parameter list
Object.keys(radios).map(function(key) { ... });
// ^ no r
r
is now a free variable inside the callback and will be looked up in higher scopes.
To learn more about closures, have a look at this MDN article.
We can simplify the mapping by using ES6 arrow functions, which you can use if you transpile your code with Babel or jsx --harmony
:
{Object.keys(radios).map(key =>
<div key={key}>
<label forHTML={key}>
<input ... nChange={this.selectHandlerLoop} /> {radios[key].radio}
</label>
</div>
)}
Because this
inside arrow functions is lexically scoped, it will refer to the this
value of the render
method, which is your React ponent.