By Kurai


2018-07-11 23:57:12 8 Comments

Below is my code and I got a feeling I am really doing this wrong. I am new to react and I been spending many hours trying to figure this out with no luck.

I am trying to get users to input values of age, gender, height, weight etc..and then make the BMR box update with a value.

What i have so far is when the user clicks "Calculate for BMR" the onClick function spits out the correct result, but I have no clue how to get the value to appear in the "BMR input box" without any sort of refreshing.

Any help would be appreciated. Thanks

 class Calculator extends React.Component {
    constructor(props) {
        super(props);
        this.state = {};

        this.handleGenderChange = this.handleGenderChange.bind(this);
        this.handleAgeChanged = this.handleAgeChanged.bind(this);
        this.handleWeightChanged = this.handleWeightChanged.bind(this);
        this.handleFeetChanged= this.handleFeetChanged.bind(this);
        this.handleInchesChanged=this.handleInchesChanged.bind(this);


    }

    handleGenderChange = (event) => {
        this.setState({Gender: event.target.value});
    }

    handleAgeChanged = (event) => {
        this.setState({Age: event.target.value});
    }

    handleWeightChanged = (event) => {
        this.setState({Weight: event.target.value});
    }

    handleHeightChanged = (event) => {
        this.setState({Height: event.target.value});
    }

    handleFeetChanged = (event) => {
        this.setState({Feet: event.target.value});
    }
    handleInchesChanged = (event) => {
        this.setState({Inches: event.target.value});
    }
    onClick= (event) => {
        event.preventDefault();
        console.log(this.state);

        const totalHeight = Number(this.state.Feet) * 12 + Number(this.state.Inches);

        if(this.state.Gender == 'Male'){
            var BMR = 66 + (6.23 * Number(this.state.Weight)) + (12.7 * totalHeight) - (6.8 * Number(this.state.Age));
            console.log(BMR);
        }

        if(this.state.Gender == 'female'){
            var BMR = 655 + (4.35 * Number(this.state.weight)) + (4.7 * totalHeight) - (4.7 * Number(this.state.age));
            console.log(BMR);
        }

    }

    render() {
        return (
            <div>

                    <Container>
                        <form>
                            <h3>Calories/TDEE Calculator</h3>

                            <div className="form-group">
                            <select className="form-control" value={this.state.Gender} onChange={this.handleGenderChange}>
                                <option disabled selected value> -- Gender-- </option>
                                <option value="Male">Male</option>
                                <option value="Female">Female</option>
                            </select>
                            </div>

                            <div className="form-group">
                            <label htmlFor="Age">Age</label>
                                <input className="form-control" 
                                onChange={this.handleAgeChanged} 
                                type="input" 
                                id="Age" 
                                name="Age" 
                                placeholder="Enter an Age"
                                value={this.state.Age} 
                                /> 
                            </div>

                            <div className="form-group">
                            <label htmlFor="Weight">Weight (lbs)</label>
                                <input className="form-control" 
                                onChange={this.handleWeightChanged} 
                                type="input" 
                                id="Weight" 
                                name="Weight" 
                                placeholder="Enter Weight"
                                value={this.state.Weight} 
                                /> 
                            </div>

                            <div className="form-group">
                            <label>"Height (Ft/In)"</label>
                                <input type="input" 
                                name="Feet"  
                                placeholder="Feet" 
                                onChange={this.handleFeetChanged} 
                                value={this.state.Feet} 
                                 /> 

                                <input type="input" 
                                name="Inches" 
                                placeholder="Inches" 
                                onChange={this.handleInchesChanged} 
                                value={this.state.Inches}
                                /> 
                           </div>

                            <div className="form-group">
                            <label>BMR</label>
                                <input className="form-control" 
                                id="BMR" 
                                name="BMR" 
                                value= ""
                                /> 
                            </div>
                            <button className="btn btn-lg btn-primary btn-block" onClick={this.onClick.bind(this)}>Click for BMR</button> <br />

                            &nbsp; &nbsp;

                        </form>

                    </Container>

            </div>


        );
    }

}
export default Calculator;

EDIT: Thanks everyone for taking your time to help, it worked :D. I learned from all your replies.

3 comments

@Mike 'Pomax' Kamermans 2018-07-12 00:15:12

You don't have anything that renders this.state.BMR so it's not too surprising you don't see it anywhere. Some advice: don't use nonbreaking spaces and <br>: that's what CSS is for. Also, don't use bind, use arrow notation to preserve this, there is no reason to use all these bind calls in your constructor.

And then for the actual question: you need to actually render something, so have an element that either shows the button, or shows the BMR value, based on whether you computed it:

class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  handleGenderChange(evt) {
    // you really should validate this
    this.setState({Gender: event.target.value});
  }

  ...

  render() {
    return <div>
      ...
        <inputelement onChange={evt => this.handleInchesChanged(evt) } />
      ...
      { this.showButtonOrResult() }
    </div>;
  }

  showButtonOrResult() {
    // if the button wasn't clicked yet, then `BMR` will not yet be a state value
    if (!this.state.BMR) {
      return <button className="..." onClick={evt => this.onClick(evt)>Click for BMR</button>
    } 
    // if it IS a state value, just render it
    return <div>Your BMR is: { this.state.BMR }</div>;
  }
}

So when your button is clicked, you do what you do, calculate BMR, then setState that, and render() automatically gets called again. Now there is a value to show, and instead of the button, it'll show a div with the result.

Also note that we are absolutely not using bind(this) in the constructor, because that's ridiculous. Properly handle your events with an arrow function so that you get the event, and then pass the event to the correct function, with normal this context.

@Erik B 2018-07-12 00:21:41

You need to label your state properties correctly. Your female calculation is going to spit out NaN because you're using {this.state.weight} when you're setting it as 'Weight'

Initialize your state

this.state = {
  bmr: ''
};

Set the value of your input

        <div className="form-group">
          <label>BMR</label>
          <input className="form-control"
            id="BMR"
            name="BMR"
            value={this.state.bmr}
          />
        </div>

Set the state in your onclick function

onClick = (event) => {
event.preventDefault();

let BMR;

const totalHeight = Number(this.state.Feet) * 12 + Number(this.state.Inches);

if (this.state.Gender === 'Male') {
  BMR = 66 + (6.23 * Number(this.state.Weight)) + (12.7 * totalHeight) - (6.8 * Number(this.state.Age));
  this.setState({ bmr: BMR });
} else if (this.state.Gender === 'Female') {
  BMR = 655 + (4.35 * Number(this.state.Weight)) + (4.7 * totalHeight) - (4.7 * Number(this.state.Age));
  this.setState({bmr: BMR});
}
}

@Felipe Lanza 2018-07-12 00:13:36

Just set a BMRvalue inside your state and link that to the input value.

state = {
    BMRvalue: ''
}

Then add this to your onClick function:

this.setState({
    BMRvalue: BMR
})

And slightly change your rendered input:

<div className="form-group">
<label>BMR</label>
    <input className="form-control" 
    id="BMR" 
    name="BMR" 
    value={this.state.BMRvalue}
    /> 
</div>

@Mike 'Pomax' Kamermans 2018-07-12 00:15:42

note that { BMRvalue = ''} is not proper syntax at all, with errors on both the initialisation as well as that setState you show.

@Felipe Lanza 2018-07-12 00:20:11

That was really ugly. I've edited those, thanks.

Related Questions

Sponsored Content

36 Answered Questions

[SOLVED] Scroll to the top of the page using JavaScript/jQuery?

39 Answered Questions

[SOLVED] How do I get the current date in JavaScript?

18 Answered Questions

[SOLVED] Get selected value in dropdown list using JavaScript?

3 Answered Questions

[SOLVED] Updating address bar with new URL without hash or reloading the page

17 Answered Questions

[SOLVED] Get the size of the screen, current web page and browser window

32 Answered Questions

[SOLVED] $(document).ready equivalent without jQuery

  • 2009-04-28 21:51:11
  • FlySwat
  • 814442 View
  • 1613 Score
  • 32 Answer
  • Tags:   javascript jquery

17 Answered Questions

[SOLVED] How to reload a page using JavaScript?

  • 2010-09-15 06:03:09
  • Resh
  • 612841 View
  • 520 Score
  • 17 Answer
  • Tags:   javascript

3 Answered Questions

[SOLVED] How do I get started with Node.js

  • 2010-03-01 04:09:28
  • Joneph O.
  • 1175762 View
  • 1266 Score
  • 3 Answer
  • Tags:   javascript node.js

29 Answered Questions

[SOLVED] Get current URL in JavaScript?

18 Answered Questions

[SOLVED] Modify the URL without reloading the page

Sponsored Content