状态不立即更新

时间:2018-11-28 02:06:42

标签: reactjs

我正在构建一个Web应用程序,该应用程序通过询问用户年龄,体重,性别,脚,英寸来计算BMR。用户提交表单后,应该有一个警告框,其中包含所有对象的状态。唯一的问题是,BMR是唯一保持为0的值。直到我再次单击提交,它才会更新。我正在使用两个类:Macros(main)和Form。我的代码在下面

class Macros extends React.Component{

constructor(props){
    super(props);

    this.state = {
        age: '',
        weight: '',
        male: true,
        feet: '',
        inches: '',
        BMR: 0,
    };

    this.handleAgeChange = this.handleAgeChange.bind(this);
    this.handleWeightChange = this.handleWeightChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleGenderChange = this.handleGenderChange.bind(this);
    this.handleFeetChange = this.handleFeetChange.bind(this);
    this.handleInchChange = this.handleInchChange.bind(this);
    this.calculateBMR = this.calculateBMR.bind(this);
}

handleAgeChange(event) {
    this.setState({age: event.target.value});
}

handleWeightChange(event) {
    this.setState({weight: event.target.value});
}

handleSubmit(event) {
    this.calculateBMR();
    event.preventDefault();
    alert('Age: ' + this.state.age + ' Weight: ' + this.state.weight + ' Male: ' + this.state.male 
    + ' Feet: ' + this.state.feet + ' Inches: ' + this.state.inches + ' BMR: ' + this.state.BMR) 
}

handleGenderChange(event) {
    this.setState({male: !this.state.male});
}

handleFeetChange(event) {
    this.setState({feet: event.target.value});
}

handleInchChange(event) {
    this.setState({inches: event.target.value});
}

calculateBMR() {
    let calBMR = 0;
    if(this.state.male){
        calBMR = ((10 * ((this.state.weight) / 2.20462)) + 
            (6.25 * ((this.state.feet * 30.48) + (this.state.inches * 2.54))) - 
            (5 * this.state.age)) + 5;
    }
    else {
        calBMR = ((10 * ((this.state.weight) / 2.20462)) + 
            (6.25 * ((this.state.feet * 30.48) + (this.state.inches * 2.54))) - 
            (5 * this.state.age)) - 161;
    }
    this.setState({BMR: calBMR});
}


render(){
    const title = 'Macro Apps';
    const subtitle = 'Calculate Your Macro-Nutrient Intake for Flexible Dieting';
    return (
        <div>
            <Header title={title} subtitle={subtitle} />
            <Form onAgeChange={this.handleAgeChange} onWeightChange={this.handleWeightChange}
                  onGenderChange={this.handleGenderChange} onFeetChange={this.handleFeetChange}
                  onInchChange={this.handleInchChange} onSubmit={this.handleSubmit}
            />
        </div>
    );
}
}

ReactDOM.render(<Macros />, document.getElementById('root'));

表单类

import React from 'react';

export class Form extends React.Component{
    render(){
        return (
            <div>
                <form onSubmit={this.props.onSubmit}>
                    Age:
                    <input type="text" onChange={this.props.onAgeChange}/><br />
                    Weight:
                    <input type="text" onChange={this.props.onWeightChange} /><br />
                    <label>
                    <input 
                        type="radio"
                        name="gender"
                        checked="checked"
                        onChange={this.props.onGenderChange}
                    />
                    Male
                </label>
                <label>
                    <input 
                        type="radio"
                        name="gender"
                        onChange={this.props.onGenderChange}
                    />
                    Female<br/>
                </label>
                <input type="text" onChange={this.props.onFeetChange}/>ft 
                <input type="text" onChange={this.props.onInchChange}/>in<br/>
                <input type="submit" value="Submit" />
            </form>
        </div>
    )
}
}

2 个答案:

答案 0 :(得分:2)

在ReactJS中,设置状态为异步。您可以像这样简单地将callback传递给setState方法:

setState({ "something": "needs to change" }, () => { /* will be invoked when the state changes. */ })

所以这行代码:

handleSubmit(event) {
    this.calculateBMR();
    ...
}

calculateBMR() {
    ...
    this.setState({BMR: calBMR});
}

可能看起来像这样:

handleSubmit(event) {
    this.calculateBMR(() => {
         alert('Age: ' + this.state.age + ' Weight: ' + this.state.weight + ' Male: ' + this.state.male + 
         ' Feet: ' + this.state.feet + ' Inches: ' + this.state.inches + ' BMR: ' + this.state.BMR) 
    });
}

calculateBMR(callback) {
    this.setState({ BMR: calBMR }, callback);
}

答案 1 :(得分:0)

您可以像下面那样进行更改,或尝试使用Mobx

`class Macros extends React.Component{
constructor(props){
    super(props);
    this.state = {
        age: '',
        weight: '',
        male: true,
        feet: '',
        inches: '',
        BMR: 0,
    };

    this.handleAgeChange = this.handleAgeChange.bind(this);
    this.handleWeightChange = this.handleWeightChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleGenderChange = this.handleGenderChange.bind(this);
    this.handleFeetChange = this.handleFeetChange.bind(this);
    this.handleInchChange = this.handleInchChange.bind(this);
    this.calculateBMR = this.calculateBMR.bind(this);
}

handleAgeChange(event) {
    this.setState({age: event.target.value},this.calculateBMR);
}

handleWeightChange(event) {
    this.setState({weight: event.target.value},this.calculateBMR);
}

handleSubmit(event) {

    event.preventDefault();
    alert('Age: ' + this.state.age + ' Weight: ' + this.state.weight + ' Male: ' + this.state.male 
    + ' Feet: ' + this.state.feet + ' Inches: ' + this.state.inches + ' BMR: ' + this.state.BMR) 
}

handleGenderChange(event) {
    this.setState({male: !this.state.male},this.calculateBMR);
}

handleFeetChange(event) {
    this.setState({feet: event.target.value},this.calculateBMR);
}

handleInchChange(event) {
    this.setState({inches: event.target.value},this.calculateBMR);
}

calculateBMR() {
    let calBMR = 0;
    if(this.state.male){
        calBMR = ((10 * ((this.state.weight) / 2.20462)) + 
            (6.25 * ((this.state.feet * 30.48) + (this.state.inches * 2.54))) - 
            (5 * this.state.age)) + 5;
    }
    else {
        calBMR = ((10 * ((this.state.weight) / 2.20462)) + 
            (6.25 * ((this.state.feet * 30.48) + (this.state.inches * 2.54))) - 
            (5 * this.state.age)) - 161;
    }
    this.setState({BMR: calBMR});
}


render(){
    const title = 'Macro Apps';
    const subtitle = 'Calculate Your Macro-Nutrient Intake for Flexible Dieting';
    return (
        <div>
            <Header title={title} subtitle={subtitle} />
            <Form onAgeChange={this.handleAgeChange} onWeightChange={this.handleWeightChange}
                  onGenderChange={this.handleGenderChange} onFeetChange={this.handleFeetChange}
                  onInchChange={this.handleInchChange} onSubmit={this.handleSubmit}
            />
        </div>
    );
}
}

ReactDOM.render(<Macros />, document.getElementById('root'));
`