Reputation: 435
I am new to programming and want to learn React. Currently, the concept of state is very confusing to me. In the code below, I am trying to write this simple app where I ask the user to enter number one, then save that number and then enter number two, save that number as well, and then show the total in the end. I am able to enter only one number in the input field. I don't know what to put in as value in the input field.
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Random extends Component {
state = {
numberOne: '',
numberTwo: '',
message: 'Enter number One',
showTotal: ''
};
AddNumbersInTheTextField_one = event => {
this.setState({
numberOne: parseInt(event.target.value)
});
};
AddNumbersInTheTextField_two = event => {
this.setState({
numberTwo: parseInt(event.target.value)
});
};
HandleSaveButton = () => {
this.setState(
{
numberOne: this.state.numberOne,
numberTwo: this.state.numberTwo
},
function() {
this.setState({
numberOne: '',
message: 'Enter number two'
});
}
);
};
HandleShowTotalButton = () => {
this.setState({
showTotal: this.state.numberOne + this.state.numberTwo,
message: this.state.showTotal
});
};
render() {
return (
<div>
<h1>{this.state.message}</h1>
<div>
<input
value={this.state.numberOne}
onChange={this.AddNumbersInTheTextField_one}
/>
</div>
<div>
<button onClick={this.HandleSaveButton}>Save Number</button>
<button onClick={this.HandleShowTotalButton}>Show Total</button>
<div>{this.state.showTotal}</div>
</div>
</div>
);
}
}
ReactDOM.render(<Random />, document.getElementById('root'));
Upvotes: 1
Views: 538
Reputation: 435
I was able to fix the issue by modifying my code. Thank you @fvaldez421 for the help. I will definitely use your logic when I am a bit advance in learning.
import React, { Component } from 'react'
class Random extends Component {
state ={
numberOne: '',
numberTwo: '',
inputFieldValue: '',
message: "Enter number One",
showTotal: ''
}
AddNumbersInTheTextField = (event) =>{
this.setState({
inputFieldValue: parseInt(event.target.value)
})
}
HandleSaveButton = () => {
if(this.state.numberOne === ''){
this.setState({
numberOne: this.state.inputFieldValue,
message: "Enter number Two",
inputFieldValue: ''
})
}
else if(this.state.numberTwo === ''){
this.setState({
numberTwo: this.state.inputFieldValue,
inputFieldValue: ''
})
}
}
HandleShowTotalButton = () => {
this.setState({
showTotal: (this.state.numberOne + this.state.numberTwo),
})
}
render() {
return (
<div>
{this.state.message}
<div>
<input value={this.state.inputFieldValue} onChange={this.AddNumbersInTheTextField} ></input>
</div>
<div>
<button onClick={this.HandleSaveButton}>Save Number</button>
<button onClick={this.HandleShowTotalButton}>Show Total</button>
<div>{this.state.showTotal}</div>
</div>
</div>
)
}
}
export default Random
Upvotes: 0
Reputation: 196
The problem is here:
HandleSaveButton = () => {
this.setState(
{
// there is no need to set these values because we already have them in state
numberOne: this.state.numberOne,
numberTwo: this.state.numberTwo
},
function() {
this.setState({
// you're setting your numberOne value to ''
numberOne: '',
message: 'Enter number two'
});
}
);
};
You could dry up your code a little by making your input change function universal and assigning a value to the name attributes in your input. Then simplify your code by making the handleSave dynamic, depending on the active field in state.
state = {
activeField: 'fieldOne',
fieldOne: '',
fieldTwo: '',
total: '',
message: '',
}
// this will update any shallow inputs in state
handleInputChange(e) {
const { target: { name, value } } = e;
this.setState({ [name]: value });
}
handleSave(e) {
const { activeField, fieldOne, fieldTwo } = this.state;
if (activeField == 'fieldOne') {
this.setState({
activeField: 'fieldTwo',
message: 'Enter number two.'
});
} else if (activeField == 'fieldTwo') {
// here we basically cut out the logic you have in HandleShowTotalButton,
// you may show total to handle a boolean value instead and conditionally
// render the total value after the user clicks it
this.setState({ total: fieldOne + fieldTwo });
}
}
// below is just an example of what your input should look like not the literal jsx you'll be using
render() {
// we use the activeField as a key in state to obtain our activeValue
const { activeField } = this.state;
const activeValue = this.state[activeField];
return (
// your inputs could look like this with a dynamic name and value
<input name={activeField} value={activeValue} onChange={this.handleInputChange} />
Upvotes: 2