0

may I ask for your help. I'm trying to save or store textbox data to hooks. However, upon clicking the save button the data from textbox is not yet saved to my useState. I need to click again the save button to be able to save it to hooks.

See below codes.

const [updateApprovalStatus, setupdateApprovalStatus] = useState({
  ADVISORYID: "",
  STATUS: "",
  REMARKS: "",
  REJECTEDREMARKS: "",
});

const [txtAdvisoryApprovalRemarks, settxtAdvisoryApprovalRemarks] = useState(
  ""
);
const approvalRemarksOnChange = (event) => {
  settxtAdvisoryApprovalRemarks(event.target.value);
};
const updateApproval = () => {
  if (updateApprovalStatus.STATUS === "APPROVED") {
    setupdateApprovalStatus((prevState) => ({
      ...prevState,
      REMARKS: txtAdvisoryApprovalRemarks,
    }));
    setupdateApprovalStatus((prevState) => ({
      ...prevState,
      REJECTEDREMARKS: "",
    }));
  } else if (updateApprovalStatus.STATUS === "REJECTED") {
    //console.log('save to rejected remarks')
    setupdateApprovalStatus((prevState) => ({
      ...prevState,
      REJECTEDREMARKS: txtAdvisoryApprovalRemarks,
    }));
    setupdateApprovalStatus((prevState) => ({
      ...prevState,
      REMARKS: "",
    }));
  }
  console.log("updateApprovalStatus", updateApprovalStatus); //returns the array but no remarks or rejectedremarks saved
};

Components

<TextField
    className={style.inputMaterial}
    label="Remarks"
    name="REMARKS"
    onChange={approvalRemarksOnChange}
/>
<br />
<Button color="primary" onClick={() => updateApproval()}>
  Save{" "}
</Button>

On my first click I got this

{ADVISORYID: 370, STATUS: "APPROVED", REMARKS: "", REJECTEDREMARKS: ""}

On second click, this is where value took effect. upon console log.

{ADVISORYID: 370, STATUS: "APPROVED", REMARKS: "remarks", REJECTEDREMARKS: ""}

Hoping for your understanding Thank you

Mr. Hedgehog
  • 2,644
  • 1
  • 14
  • 18
Rymrk
  • 216
  • 1
  • 3
  • 13

1 Answers1

0

You should understand how setState works. When you call setState you tell react "can you please put this into state for me?". And then you forget about it. Value is not still changed. Once react will have time, it will change state and rerun your component with new state, so the whole process is asynchronous.

When you call your console.log, react is not yet saved your new state in it's internal storage, that is why you don't get it on first run - state still the same. Try render your state (with JSON.stringify) to see state update.

Also, because it is asynchronous process, React might ignore subsequent state changes and apply only last one. It is lot easier to make all changes in one go.

Here is working example (look both in console and in render): https://jsfiddle.net/zrsfb96x/

Mr. Hedgehog
  • 2,644
  • 1
  • 14
  • 18
  • Hi @ezhikov, noted on this and I get it. However, after the If, else if on updateApproval function. I'm going to save it to database using axios.post('API', updateApprovalStatus) and I'm passing blank remarks value to API. Upon second click, I was able to pass the value of remarks. That's why I'm trying to display it on console.log. Thank you. Hope you can help me. – Rymrk Mar 08 '21 at 03:56
  • You know your current state and you know your update. You can construct updated state and send it to the server. I modified my example: https://jsfiddle.net/Lwmygn1c/ – Mr. Hedgehog Mar 08 '21 at 06:38
  • @ezhikov is right! –  Mar 08 '21 at 13:51