I am working on a react app. It has a button Add to add line to calculate volume. Every line contains 2 input fields for values of thickness and surface area correspondingly. I noticed if thickness was inputted and user is starting to enter surface area, the volume will be rendered only after second symbol.
For example, thickness - inputted 100, surface - 1 and volume 0 (but expected 0,1). Then surface - 10 and volume 1 (as expected). The same if input surface 100 and thickness 1 --> volume 0 (expected 0,1).
Could someone explain how to fix the issue, please? Thank you for you help.
import { useState } from "react";
const App = () => {
const [datas, setDatas] = useState([]);
const handleChange = (index) => (event) => {
let currentValue = +event.target.value;
if (event.target.name === "thickness") {
let newArr = [...datas];
newArr[index] = { ...newArr[index], thickness: currentValue };
if (datas[index].thickness && datas[index].surface) {
newArr[index] = {
...newArr[index],
volume: (currentValue * newArr[index].surface) / 1000,
};
}
setDatas(newArr);
}
if (event.target.name === "surface") {
let newArr = [...datas];
newArr[index] = { ...newArr[index], surface: currentValue };
if (datas[index].thickness && datas[index].surface) {
newArr[index] = {
...newArr[index],
volume: (newArr[index].thickness * currentValue) / 1000,
};
}
setDatas(newArr);
}
};
const removeItem = (index) => {
let newItems = datas.filter((product, id) => id !== index);
setDatas(newItems);
};
const addLine = () => {
setDatas([
...datas,
{
thickness: 0,
surface: 0,
volume: 0,
},
]);
};
return (
<>
{datas.map((data, index) => {
return (
<li key={index}>
<input
label="thickness mm"
name="thickness"
id={index}
value={data.thickness}
onChange={handleChange(index)}
/>
<input
name="surface"
label="surface m¬2"
id={index}
value={data.surface}
onChange={handleChange(index)}
/>
<span>Volume {data.volume}</span>
<button onClick={() => removeItem(index)}>X</button>
</li>
);
})}
<button onClick={addLine}>Add</button>
</>
);
};
export default App;
You have a problem with your conditions, you are checking if the old values are full instead of checking newArr or currentValue variables.
This is an example:
If we give thickness the value 100 when the user starts entering the input surface, you check if the variable datas[index].surface (old value) is full instead of checking the current value.
const handleChange = (index) => (event) => {
let currentValue = +event.target.value;
if (event.target.name === "thickness") {
let newArr = [...datas];
newArr[index] = { ...newArr[index], thickness: currentValue };
if (newArr[index].thickness && newArr[index].surface) { //you should verify the latest values not old
newArr[index] = {
...newArr[index],
volume: (currentValue * newArr[index].surface) / 1000
};
}
setDatas(newArr);
}
if (event.target.name === "surface") {
let newArr = [...datas];
newArr[index] = { ...newArr[index], surface: currentValue };
if (newArr[index].thickness && newArr[index].surface) { //you should verify the latest values not old
newArr[index] = {
...newArr[index],
volume: (newArr[index].thickness * currentValue) / 1000
};
}
setDatas(newArr);
}
};
https://codesandbox.io/s/intelligent-liskov-dghgu?file=/src/App.js:99-939