Setting the value of a variable as previous state value of another variable

Viewed 492

I am new to reactjs and in my code I am trying to assign the value of starting balance in a form as the closing balance of the previous record. The initial values of the form are the response of an API call (defined here in the get_schedule array ). The initial starting balance is the total principal and is static. The user can make changes to the principal and interest amounts which in turn results in change of values of EMI amount, closing balance, starting balance and the total of principals and interests. I would like to know how I must handle the values of starting balances.

import React, { Component } from "react";
import ReactDOM from "react-dom";

import "./styles.css";
class App extends Component {
  constructor(props) {
    super();
    this.state = {
      get_interest: 5,
      get_principal: 5,
      get_starting_balance: 10,
      get_closing_balance: 0,
      get_emi_date: "2018-09-12",
      get_emi_amount: 0,
      field: "",
      get_schedule: [
        {
          amount: 5151,
          closing_balance: 5050,
          date: "2019-02-03",
          discount: 0,
          interest: 200,
          principal: 4951,
          starting_balance: 10000
        },
        {
          amount: 5151,
          closing_balance: 0,
          date: "2019-03-03",
          discount: 0,
          interest: 101,
          principal: 5050,
          starting_balance: 5050
        }
      ]
    };
  }
  handleAmortScheduleChange = (key, field) => e => {
    const value = e.target.value;
    const { get_schedule, get_emi_amount } = this.state;
    const old_schedule = get_schedule[key];
    const new_get_schedule = [...get_schedule];
    new_get_schedule[key] = {
      ...old_schedule,
      [field]: value,
      amount: get_emi_amount,
      closing_balance: old_schedule.starting_balance - get_emi_amount
    };

    this.setState({
      get_schedule: new_get_schedule,
      get_emi_amount:
        parseInt(new_get_schedule[key].principal) +
        parseInt(new_get_schedule[key].interest)
    });
    var arr = document.getElementsByName("get_schedule_principal_here");
    var tot = 0;
    for (var i = 0; i < arr.length; i++) {
      if (parseInt(arr[i].value)) tot += parseInt(arr[i].value);
    }
    document.getElementById("get_total_principal").value = tot;
    var arr_interest = document.getElementsByName("get_schedule_interest_here");
    var tot_interest = 0;
    for (var i = 0; i < arr_interest.length; i++) {
      if (parseInt(arr_interest[i].value))
        tot_interest += parseInt(arr_interest[i].value);
    }
    document.getElementById("get_total_interest").value = tot_interest;
  };
  render() {
    const { get_schedule, get_emi_amount } = this.state;
    return (
      <div className="App">
        {this.state.get_schedule.map((row, key) => (
          <div key={key} className="row aaaa">
            <div className="getAmort-form-group col-xs-12 col-sm-12 col-md-2 col-lg-2">
              <input
                ref="get_schedule_emi_date"
                type="date"
                required="required"
                id="get_schedule_emi_date"
                value={row.date}
              />
              <label for="input" className="getAmort-control-label">
                EMI Date
              </label>
              <i className="getAmort-bar" />
            </div>
            <div className="getAmort-form-group col-xs-12 col-sm-12 col-md-2 col-lg-2">
              <input
                ref="get_schedule_emi_amount"
                type="number"
                required="required"
                id="get_schedule_emi_amount"
                value={get_schedule[key].amount}
              />
              <label for="input" className="getAmort-control-label">
                EMI Amount
              </label>
              <i className="getAmort-bar" />
            </div>
            <div className="getAmort-form-group col-xs-12 col-sm-12 col-md-2 col-lg-2">
              <input
                ref="get_schedule_principal"
                type="number"
                required="required"
                id="get_schedule_principal"
                name="get_schedule_principal_here"
                value={get_schedule[key].principal}
                onChange={this.handleAmortScheduleChange(key, "principal")}
                onKeyUp={this.handleAmortScheduleChange(key, "principal")}
              />
              <label for="input" className="getAmort-control-label">
                Principal
              </label>
              <i className="getAmort-bar" />
            </div>
            <div className="getAmort-form-group col-xs-12 col-sm-12 col-md-2 col-lg-2">
              <input
                ref="get_schedule_interest"
                type="number"
                required="required"
                id="get_schedule_interest"
                value={get_schedule[key].interest}
                onChange={this.handleAmortScheduleChange(key, "interest")}
                onKeyUp={this.handleAmortScheduleChange(key, "interest")}
              />
              <label for="input" className="getAmort-control-label">
                Interest
              </label>
              <i className="getAmort-bar" />
            </div>
            <div className="getAmort-form-group col-xs-12 col-sm-12 col-md-2 col-lg-2">
              <input
                ref="get_schedule_starting_balance"
                type="number"
                required="required"
                id="get_schedule_starting_balance"
                value={row.starting_balance}
              />
              <label for="input" className="getAmort-control-label">
                Starting Balance
              </label>
              <i className="getAmort-bar" />
            </div>
            <div className="getAmort-form-group col-xs-12 col-sm-12 col-md-2 col-lg-2">
              <input
                ref="get_schedule_closing_balance"
                type="number"
                required="required"
                id="get_schedule_closing_balance"
                value={get_schedule[key].closing_balance}
              />
              <label for="input" className="getAmort-control-label">
                Closing Balance
              </label>
              <i className="getAmort-bar" />
            </div>
          </div>
        ))}
        <div className="row">
          <div className="getAmort-form-group col-xs-12 col-sm-12 col-md-2 col-lg-2">
            <input type="number" required="required" id="get_total_principal" />
            <label for="input" className="getAmort-control-label">
              Total Principal
            </label>
            <i className="getAmort-bar" />
          </div>

          <div className="getAmort-form-group col-xs-12 col-sm-12 col-md-2 col-lg-2">
            <input type="number" required="required" id="get_total_interest" />
            <label for="input" className="getAmort-control-label">
              Total Interest
            </label>
            <i className="getAmort-bar" />
          </div>
        </div>
      </div>
    );
  }
}
const rootElement = document.getElementById("root");

ReactDOM.render(<App />, rootElement);

I want to implement something like this in the handleAmortScheduleChange function:

if(key>0) { this.state.new_get_schedule.starting_balance = parseInt(this.state.new_get_schedule[key-1].closing_balance); } The link to working code is https://codesandbox.io/s/w8x9j9o15.

1 Answers

why are you even using react if you look at it like DOM wtf, who told you to use getElementById etc. there's so many simple examples online that do simple stuff like this that I am surprised how you came up with this

input should have a value that is connected to state, you update the state with onChange and the value will change cuz it listens to the changes to the state the problem ppl who didn't read docs stumble upon, the changes will be 1 step behind cuz the setState doesn't update immediately - it's not synchronous. So you'd have to use the 2nd argument of setState to execute once it's done updating the state, or a different method

codesandbox

Related