I'm trying to get inputs from 3 fields in React and then doing some behind the scenes math. For the life of me I can't get the 3rd field (partprice) to be added to the rest, was hoping someone would be able to see what I'm doing wrong. I can get all 3 fields to console.log with the event values, but when the math completes, the 3rd field is always missing.
import React, { useState, userForm } from "react";
import moment from "moment";
export default function Form() {
const [labor, setLabor] = useState("");
const [mileage, setMileage] = useState("");
const [partprice, setPartPrice] = useState("");
const [finalRate, setFinalRate] = useState("");
const cancelCourse = () => {
console.log("canceCourse Link 10 form.JS");
setLabor("");
setMileage("");
setPartPrice("");
};
const handleSubmit = (event) => {
event.preventDefault();
let hourlyRate = labor * 80 + (mileage * 0.085 + 7.5) + partprice;
let roundedRate = Math.round(hourlyRate * 100) / 100;
setFinalRate(roundedRate);
cancelCourse();
};
const changeLabor = (event) => {
setLabor(event.target.value);
};
const changeMileage = (event) => {
setMileage(event.target.value);
};
const changePartPrice = (event) => {
setPartPrice(event.target.value);
};
return (
<div className="page">
<form id="create">
<input
className="form-input"
id="date"
placeholder={moment().format("dddd")}
></input>
<input
className="form-input"
id="link"
value={labor}
placeholder="Enter Labor/Travel Time"
onChange={changeLabor}
></input>
<input
className="form-input"
id="comment"
value={mileage}
placeholder="Enter Miles Traveled"
onChange={changeMileage}
></input>
<input
className="form-input"
id="tags"
value={partprice}
placeholder="Enter Parts Price"
onChange={changePartPrice}
></input>
<button className="submit" onClick={handleSubmit}>
Submit
</button>
</form>
<div className="finalrate">
<h1>{finalRate}</h1>
</div>
</div>
);
}
Your code is treating number as a string value and concatenating it to the end of the calculation. Instead of ...
labor * 80 + (mileage * 0.085 + 7.5) + partprice;
Try ...
labor * 80 + (mileage * 0.085 + 7.5) + Number(partprice);
There are many ways to perform validation, but this simple example gives you an idea what's happening.
You can clean up your code quite a bit...
Here's a custom hook to handle your form:
import { useState } from 'react';
export const useForm = (initialValues) => {
const [values, setValues] = useState(initialValues);
return {
values,
handleChange: (e) => {
setValues({
...values,
[e.target.name]: e.target.value,
});
},
reset: () => setValues(initialValues),
};
};
Then you can use it in your component like so:
import React, { useState } from "react";
import moment from "moment";
import { useForm } from "./useForm"; //import it here
export default function Form() {
const { values, handleChange, reset } = useForm({
labor: "",
milage: "",
partprice: ""
}); //use it here
const [finalRate, setFinalRate] = useState("");
const handleSubmit = event => {
event.preventDefault();
let hourlyRate = values.labor * 80 + (values.milage * 0.085 + 7.5) + parseInt(values.partprice);
let roundedRate = Math.round(hourlyRate * 100) / 100;
setFinalRate(roundedRate);
reset();
};
return (
<div className="page">
<form id="create" onSubmit={handleSubmit}>
<input
className="form-input"
id="date"
placeholder={moment().format("dddd")}
/>
<input
className="form-input"
id="link"
name="labor"
value={values.labor}
placeholder="Enter Labor/Travel Time"
onChange={handleChange}
/>
<input
className="form-input"
id="comment"
name="milage"
value={values.milage}
placeholder="Enter Miles Traveled"
onChange={handleChange}
/>
<input
className="form-input"
id="tags"
name="partprice"
value={values.partprice}
placeholder="Enter Parts Price"
onChange={handleChange}
/>
<button className="submit">Submit</button>
</form>
<div className="finalrate">
<h1>{finalRate}</h1>
</div>
</div>
);
}
Live demo: https://stackblitz.com/edit/react-7ylsha?file=index.js
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With