I have an AddProduct component which's child is Furniture component (code seen below) which has 3 children - 3 input fields. Changing input values automatically updates dimensions state in Furniture.
After submiting form on AddProduct component I want to save dimensions to database in format ..x..x.. (example: 120x100x200) using components Furniture constant dimensionsArray.
The error is that parent component AddProduct uses the penultimate state not the latest.
Example of error: If I enter height: 123, width: 123, length: 123 then component AddProduct saves dimensions as 123x123x12 missing the last entered value.
How can I fix this issue without using Class approach (meaning without componentDidMount or setState)?
Howl form including link to github can be seen here: http://tedisproject.infinityfreeapp.com/addproduct
import { useState, useRef, forwardRef, useImperativeHandle } from "react";
import FurnitureHeight from "./FurnitureHeight";
import FurnitureWidth from "./FurnitureWidth";
import FurnitureLength from "./FurnitureLength";
const Furniture = forwardRef((props, ref) => {
const [dimensions, setDimensions] = useState({
height: "",
width: "",
length: "",
});
const changeDimensions = (e) => {
const { name, value } = e;
setDimensions((prevState) => ({
...prevState,
[name]: value,
}));
const dimensionsArray = [
dimensions["height"],
dimensions["width"],
dimensions["length"],
];
props.setValue({
value: dimensionsArray.join("x"),
name: "specificAttribute",
});
};
return (
<div id="Furniture">
<FurnitureHeight
changeDimensions={changeDimensions}
changeIsValid={changeIsValid}
ref={dimensionsRef}
/>
<FurnitureWidth
changeDimensions={changeDimensions}
changeIsValid={changeIsValid}
ref={dimensionsRef}
/>
<FurnitureLength
changeDimensions={changeDimensions}
changeIsValid={changeIsValid}
ref={dimensionsRef}
/>
</div>
);
});
export default Furniture;
CodePudding user response:
The problem is that you use the value of the state to build dimensionsArray
and the state update asynchronously, so you always get the old value. To solve this you can set the new dimensions in a variable and use it to update the state and build your array:
const changeDimensions = (e) => {
const { name, value } = e;
const newDimensions = {
...dimensions,
[name]: value
};
setDimensions(newDimensions);
const dimensionsArray = [
newDimensions["height"],
newDimensions["width"],
newDimensions["length"],
];
props.setValue({
value: dimensionsArray.join("x"),
name: "specificAttribute",
});
};