Home > Blockchain >  Ensuring React set hook runs synchronously in order
Ensuring React set hook runs synchronously in order

Time:10-23

I have a react state that contains an array of objects that look like this {ID: 7, LicenseNumber: 'Testing123', LicenseCreator: 7, added: true}

To manipulate the individual values of this object, I have prepared a function that looks like this:

const updateLicenseInfo = (index, licenseInfoKey, licenseInfoVal) => {
    const foundLicenseInfo = { ...licenseInfo[index] };
    const licenseInfoItems = [...licenseInfo];
    foundLicenseInfo[licenseInfoKey] = licenseInfoVal;
    licenseInfoItems[index] = foundLicenseInfo;
    setLicenseInfo([...licenseInfoItems]);
};

My problem is when I run this function twice in a row, I believe the asynchronous nature of hooks only causes the last function to run.

For example, when I make an API call and then try to update the ID, then the added field, ID will be null but added will have changed. Here is that example:

postData('/api/licenseInfo/createLicenseInfoAndCreateRelationship', {
        LicenseNumber,
        RequestLineItemID: procurementLine.ID
    })
        .then((res) => res.json())
        .then((r) => {
            updateLicenseInfo(licenseIndex, 'ID', r.ID);
            updateLicenseInfo(licenseIndex, 'added', true);
        })

How Can I ensure that this function runs and then the next function runs synchronously

CodePudding user response:

How about refactoring your initial function to take an array of objects as parameters, something with the structure {key: "", val: ""} and then iterating over that array in your function, adding all the values to the paired keys and calling setState only once, with all the new changes

const updateLicenseInfo = (index, pairs) => {
    const foundLicenseInfo = { ...licenseInfo[index] };
    const licenseInfoItems = [...licenseInfo];
    pairs.forEach((pair)=>{
      foundLicenseInfo[pair.key] = pair.value;
    });
    licenseInfoItems[index] = foundLicenseInfo;
    setLicenseInfo([...licenseInfoItems]);
};

and called like this

updateLicenseInfo(licenseIndex, [{key:'ID', value:r.ID},
{key:'added', value:true}]);
  • Related