Home > Enterprise >  How to use updated state right after updating state without using Class approach in React?
How to use updated state right after updating state without using Class approach in React?

Time:08-09

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",
  });
};
  • Related