Reputation: 1316
I have a React-class (JSX) that contains following (slightly simplified here) code:
var Select = React.createClass({
onChange: function (ev) {
console.log(ev.target.value);
},
render: function() {
var optionsHtml = this.state.options.map(function (el) {
console.log(this.props.getValue(el);
return (
<option key={this.props.getValue(el)}
value={this.props.getValue(el)}> { this.props.getLabel(el) }
</option>
)
});
return <select onChange={this.onChange}>
{optionsHtml}
</html>
}
In the render-function, console.log returns Integers for values (i.e. 1, 2, 3) when initializing the Options-HTML and setting the values, however inside the onChange-method value is a String (i.e. "1", "2", "3") when the actual Select-box value is changed.
One way to fix this would be to check and cast the value to Number before using it inside onChange, but is there any other way to do it?
EDIT:
Options-array could look something like this
var options = [
{ id: 1, name: "Test" },
{ id: 2, name: "Test2" },
{ id: 3, name: "Test3" }
]
Component then could be called with getValue and getLabel -functions like this:
<Select options={options},
getValue: function(v) {
return v.id;
},
getLabel: function(v) {
return v.name;
}/>
Different type is an issue once I generate a JSON that I'm sending to backend, and I need to the conversion at some point.
Upvotes: 1
Views: 4186
Reputation: 22872
I would change render method and event listener to this:
onChange(event) {
const el = this.state.options[event.target.value];
const value = this.props.getValue(el);
},
render() {
const options = this.state.options.map((el, idx) => (
<option key={this.props.getValue(el)} value={idx}>{ this.props.getLabel(e) }</option>
));
return (
<select onChange={this.onChange}>
{ options }
</select>
)
}
Doing this, you are not getting actual value. You are telling "Pick object at index N from within predefined objects and get it's value."
Upvotes: 1
Reputation: 5637
When your onChange
function executes and attempts to read the value
of an option tag, it's important to remember that all attributes will be read as strings.
With that being said, note that
onChange: function (ev) {
console.log(ev.target.value);
// ^^^^^^^^^^^^^^^ always string
}
So each time you want to handle a value in your onChange
function, you must cast the value to an number. Something like this should do the trick:
onChange: function (ev) {
var valueInt = parseInt(en.target.value, 10);
console.log(valueInt);
}
Or if the value isn't necessarily going to be a number, you can attempt to parse it as a number if applicable:
onChange: function (ev) {
var valueInt;
try{
valueInt = parseInt(en.target.value, 10);
}catch(e){
// handle value not being a number if unexpected
}
console.log(valueInt);
}
Upvotes: 5