Обновление данных в форме, расчет процетов

Столкнулся с проблемой с обновлением данных в форме по расчет процентов. Форма творит чудеса и не пойму логику.

Вот код:

const defaultContract: Contract = {
    contract_price: 0,
    contract_price_avans: 0
}

function Contract(): JSX.Element {
    const [contract, setContract] = useState<Contract>({ ...defaultContract })

function onChangeHandler(e: ChangeEvent<HTMLInputElement>) {
        const name = e.target.name;
        let value = e.target.value;
        let newContract = {
            ...contract,
            [name]: value,
        };

        if (name === 'contract_price') {
            let contract_price_avans = parseFloat(value) * 40 / 100;
            newContract.contract_price_avans = contract_price_avans;
        }
        setContract(newContract);
    }


    return (
        <>
         <h3 className="pb-4">Цена Договора и порядок расчетов</h3>
                        <div className="row">
                            <div className="col-md-4">
                                <label className="form-label">Цена договора</label>
                                <input type="number" className="form-control" name="contract_price" onChange={onChangeHandler} defaultValue={contract?.contract_price} />
                            </div>
                            <div className="col-md-8">
                            </div>
                        </div>
                        <div className="col-md-4">
                            <label className="form-label">Аванс покупателя</label>
                            <input type="number" className="form-control" name="contract_price_avans" onChange={onChangeHandler} defaultValue={contract.contract_price_avans} />
                        </div>

        </>
    );
}

Когда я вбиваю цифры в инпут contract_price , то во втором инпуте contract_price_avans корректно все считается и все ок и выводиться данные в инпуте.

Но как только я вбиваю данные contract_price_avans, то все ломается.

Я снова вбиваю данные в форму contract_price, но инпут contract_price_avans уже ничего не меняет и остовляет последние введенные данные без изменений.

Подскажите как застваить инпут contract_price_avans меняться?


Ответы (1 шт):

Автор решения: Sergey Philippenko

Вот тут проблема

let newContract = {
  ...contract,
  [name]: value,
};

Чтобы обновить стейт на основе старого значения, нужно использовать

setContract((prevContract) => {
  let newContract = {
    ...prevContract,
    [name]: value,
  }
  if (name === 'contract_price') {
    let contract_price_avans = parseFloat(value) * 40 / 100;
    newContract = {
      ...newContract,
      contract_price_avans: contract_price_avans;
    }
  }
  return newContract
});
→ Ссылка