Как суммировать значения нескольких входов, используя событие onChange | ReactJS - PullRequest
1 голос
/ 21 апреля 2020

У меня есть несколько входов, где пользователь заполняет эти входы числами. Мне нужен способ суммировать значения этих входов, когда пользователь вводит данные на любом входе.

Мой код

const [values,set_values] = useState({
    sales:'',
    bank_deposit:'',
    supply:'',
    expenses:''
})

const values_handler = (e) => {
    let name= e.target.name;
    let value= e.target.value;
    values[name]=value;
    set_values(values)

    // Calling the method to sum the value
    calc_total(value) 
}

const [total,set_total]=useState(0);

const calc_total = (value) => {
    total +=value;
    set_total(total)
}

<input type='number' onChange={value_handler} name='sales' />
<input type='number' onChange={value_handler} name='bank_deposit' />
<input type='number' onChange={value_handler} name='supply' />
<input type='number' onChange={value_handler} name='expenses' />

Проблема

Проблема в том, что значения суммируются каждый раз, когда значение ввода получает изменение, так что, если пользователь вводит 15, он суммирует 1, затем 5, поскольку метод выполняется, когда происходит изменение в значение ввода.

Ответы [ 3 ]

2 голосов
/ 21 апреля 2020
  • Вы не должны изменять значения состояния.
  • обновления состояния асин c.
  • вам не нужно использовать значение каждого onChange, вместо этого используйте значения состояния для обновления общего значения

Предполагая, что вы хотите суммировать значения продаж, bank_deposit, supply и expeses, вы можете получить они из штатов делают это, как показано ниже

const [values,set_values] = useState({
    sales:'',
    bank_deposit:'',
    supply:'',
    expenses:''
})

const values_handler = (e) => {
    let name= e.target.name;
    let value= e.target.value;
    const newValues = {
        ...values,
        [name]: value
    } 
    set_values(newValues)

    // Calling the method to sum the value
    calc_total(newValues) 
}

const [total,set_total]=useState(0);

const calc_total = (newValues) => {
    const { sales, bank_deposit, expenses, supply} = newValues;
    const newTotal = parseInt(sales) + parseInt(bank_deposit) + parseInt(expenses) + parseInt(supply)
    setTotal(newTotal)

} 

<input type='number' onChange={value_handler} name='sales' />
<input type='number' onChange={value_handler} name='bank_deposit' />
<input type='number' onChange={value_handler} name='supply' />
<input type='number' onChange={value_handler} name='expenses' />
0 голосов
/ 21 апреля 2020
const Solution = () => {
  const [input_values, set_inputvalues] = useState({
    sales: 0,
    bank_deposit: 0,
    supply: 0,
    expenses: 0
  });

  const [total, set_total] = useState(0);

  useEffect(() => {
    const arrValues = Object.values(input_values);
    const inputTotals = arrValues.reduce((accum, curr) => (accum += curr), 0);
    set_total(inputTotals);
  }, [input_values]);

  const changeValues = ({ name, value }) => {
    set_inputvalues({ ...input_values, [name]: parseInt(value) });
  };

  return (
    <div>
      <h1>{total}</h1>
      <input
        type="number"
        onChange={({ target }) => changeValues(target)}
        name="sales"
      />
      <input
        type="number"
        onChange={({ target }) => changeValues(target)}
        name="bank_deposit"
      />
      <input
        type="number"
        onChange={({ target }) => changeValues(target)}
        name="supply"
      />
      <input
        type="number"
        onChange={({ target }) => changeValues(target)}
        name="expenses"
      />
    </div>
  );
};

Для подбора некоторых ключевых ошибок, о которых упоминали другие:

  • Не изменяйте состояние напрямую, используйте set_xxx для обновления состояния.
  • Вы устанавливаете type = "number", поэтому состояние по умолчанию должно быть цифрой c, то есть продажи: 0
  • Не забудьте проанализировать значения int, если цифра c.
0 голосов
/ 21 апреля 2020

попробуйте это:

const [values,set_values] = useState({
    sales:'',
    bank_deposit:'',
    supply:'',
    expenses:''
})

const values_handler = (e) => {
    let name= e.target.name;
    let value= e.target.value;
    set_values({...values , [name]: value})

// Calling the method to sum the value
calc_total(values) 
}

const [total,set_total]=useState(0);

const calc_total = (values) => {
    aux = 0
    for (var key in values){
        aux += values[key]
    }
    set_total(aux)
}

<input type='number' onChange={value_handler} name='sales' />
<input type='number' onChange={value_handler} name='bank_deposit' />
<input type='number' onChange={value_handler} name='supply' />
<input type='number' onChange={value_handler} name='expenses' />

Примечания: Использование рекомендаций Криса Г. в комментариях

...