функция setState не определена - PullRequest
0 голосов
/ 17 декабря 2018

Я новичок в ReactJS и пытаюсь изменить значения формы, которая заполняется ответом на вызов API.Я хочу иметь возможность изменять принципалы, полученные в каждой строке, и получать их сумму в другом поле.Функция обработчика onChange:

handleAmortScheduleChange(field , key ,e  ){
            const value = e.target.value;

            this.setState({
            [get_schedule[key][field]] : value,
            [get_emi_amount]:get_schedule[key]["principal"] + get_schedule[key]["interest"],
            [get_schedule[key]["closing_balance"]] : get_schedule[key]["starting_balance"] - get_emi_amount

           });                         
            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;

        }

Код JSX:

{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"></i>
    </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={row.amount}/>
        <label for="input" className="getAmort-control-label">EMI Amount</label><i className="getAmort-bar"></i>
    </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={row.principal} onChange={this.handleAmortScheduleChange.bind(this, "principal",key)}/>
        <label for="input" className="getAmort-control-label">Principal</label><i className="getAmort-bar"></i>
    </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={row.interest} onChange={this.handleAmortScheduleChange.bind(this, "principal",key)} />
        <label for="input" className="getAmort-control-label">Interest</label><i className="getAmort-bar"></i>
    </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"></i>
    </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={row.closing_balance}/>
        <label for="input" className="getAmort-control-label">Closing Balance</label><i className="getAmort-bar"></i>
    </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"></i>
    </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"></i>
    </div>
</div>

get_schedule - это массив массивов в ответе API, содержащий значения для всехполя в форме.По сути, я пытаюсь изменить значения для принципала и интереса, введенные пользователем, и установить их соответствующие значения в массиве get_schedule.

Ошибка, которую я получаю в функции handleAmortScheduleChange, равна Uncaught ReferenceError: get_schedule is not defined,Я не могу установить государство для интереса или принципала.Где я иду не так и каково было бы решение этой проблемы?

РЕДАКТИРОВАТЬ 1: По запросу, определение get_schedule и некоторых других параметров в классе компонентов.

class LoanDetails extends Component {

    constructor(props) {
        this.state={
            get_schedule            : [],
            get_interest            : 0,
            get_principal           : 0,
            get_starting_balance    : 0,
            get_closing_balance     : 0,
            get_emi_date            : 0,
            get_emi_amount          : 0,
     }
}

Значениеустановите get_schedule из ответа API:

get_schedule: [{discount: 0, amount: 501, starting_balance: 1000, interest: 1, date: "2019-01-06",…},…]
0: {discount: 0, amount: 501, starting_balance: 1000, interest: 1, date: "2019-01-06",…}
amount: 501
closing_balance: 500
date: "2019-01-06"
discount: 0
interest: 1
principal: 500
starting_balance: 1000
1: {discount: 0, amount: 501, starting_balance: 500, interest: 1, date: "2019-02-06", closing_balance: 0,…}
amount: 501
closing_balance: 0
date: "2019-02-06"
discount: 0
interest: 1
principal: 500
starting_balance: 500

Ответы [ 4 ]

0 голосов
/ 20 декабря 2018

Я наконец внес некоторые изменения и заставил свой код работать.

  class Loan extends Component {
  constructor(props) {
    super(props);
    this.state = {

      field: "",
      get_schedule: [
        {
          amount: 2000,
          principal: 0,
          discount: 0,
          date: "2019-01-06",
          interest: 0,
          starting_balance: 1000,
          closing_balance: 0
        },
        {
          amount: 3000,
          principal: 0,
          discount: 0,
          date: "2019-02-06",
          interest: 0,
          starting_balance: 1500,
          closing_balance: 0
        }
      ]
    };
  }
  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,
      closing_balance: old_schedule.starting_balance - get_emi_amount
    };
    this.setState({
      get_schedule: new_get_schedule,
      get_emi_amount: old_schedule.principal + old_schedule.interest
      // [get_schedule[key][field]]: value,
      // [get_emi_amount]: get_schedule[key]["principal"] + get_schedule[key]["interest"],
      // [get_schedule[key]["closing_balance"]]: get_schedule[key]["starting_balance"] - get_emi_amount,
    });
    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;
  };

  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")}
              />
              <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")}
              />
              <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>
    );
  }
}
0 голосов
/ 17 декабря 2018

Если ошибка setState не определена, вы теряете этот контекст.Вы могли бы попробовать функции стрелок для вашей handleAmortScheduleChange функции?

    handleAmortScheduleChange = (field , key ,e  ) => {
        const value = e.target.value;

        this.setState({
        [get_schedule[key][field]] : value,
        [get_emi_amount]:get_schedule[key]["principal"] + get_schedule[key]["interest"],
        [get_schedule[key]["closing_balance"]] : get_schedule[key]["starting_balance"] - get_emi_amount

       });                         
        var arr = document.getElementsByName('get_schedule_principal_here');
        console.log(arr.length);
        console.log(arr);
        var tot=0;
        for(var i=0;i<arr.length;i++){

            if(parseInt(arr[i].value))
                tot += parseInt(arr[i].value);
                console.log(tot);
        }
        document.getElementById('get_total_principal').value = tot;

    }

Если ошибка get_schedule не определена, возможно, это связано с тем, что вы выполняете асинхронную операцию и к тому времени, когда она начинает отображатьсяфункция не определена, я настоятельно рекомендую проверить поток вашего кода.Если вы добавите больше кода, я могу дать вам больше подсказок, но в то же время попробуйте следующий синтаксис.

// double check if get_schedule is ready to use
{this.state.get_schedule && this.state.get_schedule.map((row,key) =>

    {
       /*  now map the row and key to inputs */
    }

}

Для устранения get_schedule ошибки в get_schedule вы сможете изменить свою функцию на функцию стрелки и использовать this.get_schedule

handleAmortScheduleChange = (field , key ,e  ) => {
    const value = e.target.value;

    this.setState({
    [this.get_schedule[key][field]] : value,
    [get_emi_amount]:this.get_schedule[key]["principal"] + this.get_schedule[key]["interest"],
    [this.get_schedule[key]["closing_balance"]] : this.get_schedule[key]["starting_balance"] - get_emi_amount

   });                         
    var arr = document.getElementsByName('get_schedule_principal_here');
    console.log(arr.length);
    console.log(arr);
    var tot=0;
    for(var i=0;i<arr.length;i++){

        if(parseInt(arr[i].value))
            tot += parseInt(arr[i].value);
            console.log(tot);
    }
    document.getElementById('get_total_principal').value = tot;

}

Я исправил вашу версию Sandbox для вашего кода, и вы можете найти ее здесь.

Я исправил следующие вещи:

  1. Для реагирующих меток используйте htmlFor вместо обычного for
  2. у некоторых из ваших входных данных не былоonChangeHandler Я просто оставил некоторый обработчик onchange для устранения ошибки, но убедитесь, что вы заполняете обработчик следующего ввода так, как вам нравится.(EMI_Date, EMI_Amount, CLOSING и START Обмена баланса для входов) ...
  3. основная ошибка Я использовал другой подход к настройке состояния.

Обычно, еслиобновление, которое вы хотите выполнить для состояния, зависит от текущего состояния, мы используем приведенный ниже синтаксис, поскольку он безопаснее:)

 this.setState(prevState => ({
      value: prevState.value + 1
    })); 

https://codesandbox.io/s/o4k6nmr4l5

Дайте мне знать, что вы думаете?ошибки нет, но я ничего не знаю о вычислениях этой формы:)

0 голосов
/ 17 декабря 2018

Вы должны связать это в конструкторе:

this.handleAmortScheduleChange = this.handleAmortScheduleChange.bind(this);
0 голосов
/ 17 декабря 2018

Предполагая, что вы уже определили функцию get_schedule, проблема, которую я вижу, состоит в том, что вы не вызываете ее, используя слово this.

Вы должны сделать что-то вроде

this.get_schedule

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...