Reputation: 317
I am Trying to make a Simple React BMI Calculator. I am trying to implement something like when ı click the submit button i want to create new html at the bottom like
How can ı do that ? Thanks
import React, { Component } from 'react'
class Areas extends Component {
constructor(props) {
super(props)
this.state = {
kg:0,
height:0,
}
this.updateKG = this.updateKG.bind(this)
this.updateHeight = this.updateHeight.bind(this)
this.calculateBMI = this.calculateBMI.bind(this)
}
updateKG(event){
this.setState({kg:event.target.value})
}
updateHeight(event){
this.setState({height:event.target.value})
}
calculateBMI(){
this.state.totals.push(parseInt(this.state.kg) + parseInt(this.state.height))
console.log(this.state.totals)
}
render() {
return (
<div>
<div className="jumbotron text-center mt-3">
<div className="container">
<h1 className="display-4">Calculate Your BMI</h1>
<p className="lead">Calculate How fat you are ?</p>
</div>
</div>
<div className="container mt-5">
<div className="row">
<div className="col text-center">
<p>Your Kg</p>
<input type="number" min="30" onChange={this.updateKG}/>
</div>
<div className="col text-center">
<p>Your Height in cm</p>
<input type="number" min="60" onChange={this.updateHeight}/>
</div>
<div className="col text-center">
<p>Calculate Your BMI</p>
<button className="btn btn-success" type="submit" onClick={this.calculateBMI}>Submit</button>
</div>
</div>
</div>
</div>
)
}
}
export default Areas
Upvotes: 0
Views: 1573
Reputation: 1721
I've updated the snippet to show the calculations.
You were almost right but you were updating totals
without this.setState
function.
then in render
method you can just iterate over totals and thats it.
You updated snippet is here.
class Areas extends Component<any, any> {
state = {
kg: 0,
height: 0,
totals: [],
};
updateKG = (event: any) => {
this.setState({ kg: parseInt(event.target.value) });
};
updateHeight = (event: any) => {
this.setState({ height: parseInt(event.target.value) });
};
calculateBMI = () => {
// formula https://www.cdc.gov/nccdphp/dnpao/growthcharts/training/bmiage/page5_1.html
const bmi = Math.round(
(this.state.kg / this.state.height / this.state.height) * 10000,
);
console.log(bmi);
this.setState({
totals: [...this.state.totals, bmi],
});
};
render() {
return (
<div>
<div className="jumbotron text-center mt-3">
<div className="container">
<h1 className="display-4">Calculate Your BMI</h1>
<p className="lead">Calculate How fat you are ?</p>
</div>
</div>
<div className="container mt-5">
<div className="row">
<div className="col text-center">
<p>Your Kg</p>
<input type="number" min="30" onChange={this.updateKG} />
</div>
<div className="col text-center">
<p>Your Height in cm</p>
<input type="number" min="60" onChange={this.updateHeight} />
</div>
<div className="col text-center">
<p>Calculate Your BMI</p>
<button
className="btn btn-success"
type="submit"
onClick={this.calculateBMI}
>
Submit
</button>
</div>
</div>
{this.state.totals.map((total: any, i: number) => {
return <div key={i}>Calculated BMI: {total}</div>;
})}
</div>
</div>
);
}
}
Upvotes: 1
Reputation: 2256
I can see Multiple problems with your code apart from your wrong BMI formula.
You had to set state like this.setState({…this.state, height: e.target.value}) same for weight.
Type of your button is Submit but there’s no form. You may remove that.
You don’t have a property total or name it bmi in your state to hold the calculated bmi
In your calculations you have a total assumed to be an array and used push array method. Push will mutate the data and we have avoid those methods which will mutate data in react. Use spread operator instead.
[…oldArray, newValue] this will produce new array. You are safe to use array methods like map, filter, and reduce etc as they all return a new array and not mutate the array.
Upvotes: 1
Reputation: 428
You can collect your totals in an array in your state and render elements based on that:
class Areas extends Component {
constructor(props) {
super(props)
this.state = {
kg:0,
height:0,
totals: []
}
this.updateKG = this.updateKG.bind(this)
this.updateHeight = this.updateHeight.bind(this)
this.calculateBMI = this.calculateBMI.bind(this)
}
updateKG(event){
this.setState({kg:event.target.value})
}
updateHeight(event){
this.setState({height:event.target.value})
}
calculateBMI(){
// This just adds weight and height, but you can replace it with the actual calculation
const total = parseInt(this.state.kg) + parseInt(this.state.height)
this.setState({totals: this.state.totals.concat([total])});
console.log(this.state.totals)
}
render() {
return (
<div>
<div className="jumbotron text-center mt-3">
<div className="container">
<h1 className="display-4">Calculate Your BMI</h1>
<p className="lead">Calculate How fat you are ?</p>
</div>
</div>
<div className="container mt-5">
<div className="row">
<div className="col text-center">
<p>Your Kg</p>
<input type="number" min="30" onChange={this.updateKG}/>
</div>
<div className="col text-center">
<p>Your Height in cm</p>
<input type="number" min="60" onChange={this.updateHeight}/>
</div>
<div className="col text-center">
<p>Calculate Your BMI</p>
<button className="btn btn-success" type="submit" onClick={this.calculateBMI}>Submit</button>
</div>
{
// Renders one element for each element in totals
this.state.totals.map(total => <p>Your BMI is {total}</p>)
}
</div>
</div>
</div>
)
}
}
Upvotes: 1
Reputation: 375
From your code, you can add another component or code. Here is the steps on how you can make them.
create a variable to show the result. First set it to "false" because we want to hide it.
create another code to display user BMI result
use that variable to show the result. For example, {showResult ? Something if true : something if false}. You have to use ternary operator to show or hide the user result
Inside the calculated Bmi function, use "setState" to change the variable to "true"
That is all the step that you have to do. Hope this help
Upvotes: 1