递增和递减计数器未正确设置状态

时间:2019-06-30 17:19:41

标签: javascript html reactjs

我正在尝试创建一个简单的组件来充当计数器!有两个计数器,一个用于计数重复次数,另一个用于计数提升量。由于某些原因,我编写的功能无法正常工作。

预期结果是,当我单击向上或向下箭头表示代表时,它将更新状态中的THAT编号。取消的金额也一样。

但是发生的是,当我再次单击上下箭头(比如说代表)时,它可以正常工作,并且可以正确地递增和递减,但是当我然后单击箭头来递增和递减所举的金额时,NaN会返回然后如果我点击rep箭头,那也会返回NaN。

这是我的相关代码:

class TrackProgress extends Component {
  constructor(props) {
    super(props);
    this.state = {
      id: parseInt(this.props.match.params.id),
      exercise: [],
      trackProgress: {
        exercise_id: parseInt(this.props.match.params.id),
        date: "",
        reps: 0,
        amountLifted: 0
      }
    };
  }

  handleChanges = e => {
    this.setState({
      trackProgress: {
        ...this.state.trackProgress,
        [e.target.name]: e.target.value
      }
    });
  };

  repsIncrease = () => {
    this.setState({
      trackProgress: {
        reps: this.state.trackProgress.reps + 1
      }
    });
  };

  repsDecrease = () => {
    this.setState({
      trackProgress: {
        reps: this.state.trackProgress.reps - 1
      }
    });
  };

  amountLiftedIncrease = () => {
    this.setState({
      trackProgress: {
        amountLifted: this.state.trackProgress.amountLifted + 1
      }
    });
  };

  amountLiftedDecrease = () => {
    this.setState({
      trackProgress: {
        amountLifted: this.state.trackProgress.amountLifted - 1
      }
    });
  };

render() {
    return (
      <div className="track-progress-container">
        <div className="track-progress-content">
          <div className="heading">
            <h1>Start Tracking</h1>
            <h2>{this.state.exercise.exerciseTitle}</h2>
          </div>
          <form className="tracking-form-container" onSubmit={this.onSubmit}>
            <div className="rep-lift-flex">
              <div>
                <h6>REPS</h6>
                <input
                  name="reps"
                  type="text"
                  placeholder="OO"
                  value={this.state.trackProgress.reps}
                  onChange={this.handleChanges}
                />
              </div>
              <div>
                <h6>LIFTED</h6>
                <input
                  name="amountLifted"
                  type="text"
                  placeholder="OO"
                  value={this.state.trackProgress.amountLifted}
                  onChange={this.handleChanges}
                />
              </div>
            </div>
            <div className="arrow-container">
              <div className="rep-arrows">
                <img
                  src={down}
                  alt="decrease"
                  name="decrementReps"
                  className={
                    this.state.trackProgress.reps === 0 ? "inactive" : ""
                  }
                  onClick={this.repsDecrease}
                />
                <img
                  src={up}
                  alt="increase"
                  name="incrementReps"
                  onClick={this.repsIncrease}
                />
              </div>
              <div className="lift-arrows">
                <img
                  src={down}
                  alt="decrease"
                  name="decrementLifted"
                  onClick={this.amountLiftedDecrease}
                  className={
                    this.state.trackProgress.amountLifted === 0
                      ? "inactive"
                      : ""
                  }
                />
                <img
                  src={up}
                  alt="increase"
                  name="incrementLifted"
                  onClick={this.amountLiftedIncrease}
                />
              </div>
            </div>
            <h6>Date</h6>
            <input
              name="date"
              type="date"
              placeholder="e.g. June 11, 2019"
              value={this.state.trackProgress.date}
              onChange={this.handleChanges}
              className="date"
            />
            <button type="submit" className="track-btn">
              TRACK EXERCISE
            </button>
          </form>
        </div>
      </div>
    );
  }
}

export default TrackProgress;

这是我写出更具体功能之前的最初功能。他们都产生了相同的结果。

reps = event => {
    if (event.target.name === "incrementReps") {
      this.setState({
        trackProgress: {
          reps: this.state.trackProgress.reps + 1
        }
      });
    } else if (event.target.name === "decrementReps") {
      this.setState({
        trackProgress: {
          reps: this.state.trackProgress.reps - 1
        }
      });
    }
  };

  amountLifted = event => {
    if (event.target.name === "incrementLifted") {
      this.setState({
        trackProgress: {
          amountLifted: this.state.trackProgress.amountLifted + 1
        }
      });
    } else if (event.target.name === "decrementLifted") {
      this.setState({
        trackProgress: {
          amountLifted: this.state.trackProgress.amountLifted - 1
        }
      });
    }
  };

我可能会丢失关键逻辑或无法解释某些问题,我一直盯着这个看了几个小时,因此非常感谢您解决这个问题!谢谢!!

1 个答案:

答案 0 :(得分:2)

在更新销售代表或提货量时,您将替换整个trackProgress对象。您的状态是:

this.state = {
     id: parseInt(this.props.match.params.id),
     exercise: [],
     trackProgress: {
         exercise_id: parseInt(this.props.match.params.id),
         date: "",
         reps: 0,
         amountLifted: 0
     }
}

调用更新函数代表销售代表或当前替换整个trackProgress对象,而不仅仅是更新所需的属性。

repsIncrease = () => {
    this.setState({
        trackProgress: {
            reps: this.state.trackProgress.reps + 1
        }
    });
}; 

通往:

state = {
     id: 1,
     exercise: [],
     trackProgress: {
         reps: 1,
     }
}

要解决此问题,可以在repsIncrease / decrease函数中包括所有先前的属性,或使用散布运算符自动填写它们。这是固定的repsIncrease函数的示例。

repsIncrease = () => {
    this.setState({
        trackProgress: {
            ...this.state.trackProgress,
            reps: this.state.trackProgress.reps + 1
        }
    });
};