Reputation: 1207
[Noob to react]: I'm trying to do something that I think is simple, I have two number counters that have buttons to add one number to them. I want the buttons to use the same math function but pass in the property assigned to them. What ends up happening is that it seems like it's adding a string value to the prop value instead of doing a math operation and I don't fully understand why.
The simple math function:
addOne = (event) => {
var { target: { name, value } } = event
this.setState({
[name] : value + 1
});
console.log("name: " + name + "\nvalue: " + value)
}
One of the buttons:
<button type="button" name="count2" value={this.state.count2} onClick={this.addOne} >Add One</button>
Example output:
name: count2
value: 0
name: count2
value: 01
name: count2
value: 011
name: count2
value: 0111
JS fiddle: https://jsfiddle.net/Vallamost/pf7kys5e/2/
React code:
class ButtonReuse extends React.Component {
constructor(props) {
super(props)
this.state = {
count1: 0,
count2: 0,
}
}
addOne = (event) => {
var { target: { name, value } } = event
this.setState({
[name] : value + 1
});
console.log("name: " + name + "\nvalue: " + value)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Counter 1: <div>{this.state.count1}</div>
<button type="button" name="count1" value={this.state.count1} onClick={this.addOne} >Add One</button>
</label>
<br/>
<label>
Counter 2: <div>{this.state.count2}</div>
<button type="button" name="count2" value={this.state.count2} onClick={this.addOne} >Add One</button>
</label>
</form>
);
}
}
ReactDOM.render(<ButtonReuse />, document.querySelector("#app"))
Upvotes: 0
Views: 136
Reputation: 1278
Looks like a buttons value is always a string. You should not be giving the button a value like this anyways, this is very roundabout. Why not just access the state directly:
addOne = (event) => {
var { target: { name } } = event
this.setState({
[name] : this.state[name] + 1
});
console.log("name: " + name + "\nvalue: " + this.state[name])
}
Then you can just remove the value from the buttons. No string conversion necessary.
Upvotes: 1
Reputation: 15688
It's because of JavaScript's type coersion. The value that you have in your buttons is in fact a string. So when you try to execute value + 1
, JavaScript tries to resolve this by first identifying a common data-type (string) before running the calculation. To work around this, simply don't use the value stored in the button and just use the state
itself.
class ButtonReuse extends React.Component {
constructor(props) {
super(props)
this.state = {
count1: 0,
count2: 0,
}
}
addOne = (event) => {
var { target: { name, value } } = event
this.setState({
[name] : this.state[name] + 1
});
console.log("name: " + name + "\nvalue: " + value)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Counter 1: <div>{this.state.count1}</div>
<button type="button" name="count1" value={this.state.count1} onClick={this.addOne} >Add One</button>
</label>
<br/>
<label>
Counter 2: <div>{this.state.count2}</div>
<button type="button" name="count2" value={this.state.count2} onClick={this.addOne} >Add One</button>
</label>
</form>
Upvotes: 3
Reputation: 196
wrap the value
with parseInt()
as it is being received as string
from event
.
this.setState({
[name] : parseInt(value) + 1
});
if you'd console.log(typeof value)
, you'd see that it's type is string
.
Upvotes: 0
Reputation: 2828
Your addOne method is not counting correct. Try this:
addOne = (event) => {
var { target: { name, value } } = event
this.setState({
[name] : ++value
});
console.log("name: " + name + "\nvalue: " + value)
}
Upvotes: 0