javascript - React-ref-uppdatering fungerar inte utan timeout


Jag har spenderat de senaste timmarna med att försöka programmässigt ställa in ett värde på ett dynamiskt renderat HTML Select-fält i React. Även när jag kunde logga elementet i konsolen med hjälp av en ref kunde jag inte ändra dess värde. Jag har också försökt göra detta med grundläggande JavaScript DOM-manipulation, det vill säga document.getElementById(), men tyvärr gav detta samma resultat.

För mitt liv kunde jag inte lista ut vad som orsakade detta. Efter mycket trial and error lyckades jag ta reda på att min uppdateringsinstruktion fungerade när jag placerade den inuti en timeout-funktion, även med timeout satt till 0.

Min fråga är om någon kan få detta att bli begripligt för mig eftersom jag inte har någon aning om varför detta skulle vara. En lösning vore också bra eftersom detta för närvarande inte är den mest välskrivna koden.

Det finns en lista där en plats kan väljas. När detta inträffar vill jag uppdatera vissa valfält för att visa dess bundna värde som standard.

Jag har följande useEffect-hook som ska ställa in standardobjekten i selectLists baserat på locationid som väljs av användaren:

useEffect(() => {
    const setDefaultSelectItems = () => {
      for (let i = 0; i < GametypeItems.length; i++) {
        let defaultValue = 0;

        const defaultItem = GametypeItems[i].items.find(
          (item: GametypeItemItem) => {
            return item.locationid === SelectedRecordLocationid;
          }
        );

        if (defaultItem != null) defaultValue = defaultItem.itemid;

        // This is the code in question, the following does function as expected
        // (ItemSelectRefs.current as any)[i].value = defaultValue;
        // when the above line alone does not
        setTimeout(() => {
          (ItemSelectRefs.current as any)[i].value = defaultValue;
        }, 0);
      }
    };

    if (SelectedRecordLocationid != null) setDefaultSelectItems();
  }, [
    GametypeItems,
    SelectedRecordLocationid,
  ]);

Variabeln GametypeItems ser ut som följer:

{
   "gametypeid": "1",
   "name": "gametypename",
   "items": [
      {
         "itemid": 0,
         "locationid": 0,
         "item": "-"
      },
      {
         "itemid": "1",
         "locationid": "1",
         "item": "Item 1"
      },
      {
         "itemid": "2",
         "locationid": "2",
         "item": "Item 2"
      },
   ],
   ect...
},

Denna data renderas till en rullgardinslista som placeras i en cell i en react-table på följande sätt:

Cell: ({ row, index }: any) => {
   return (
      <select
         id={"item-select-" + row._original.gametypeid}
         className="form-select form-select-sm"
         disabled={selectedRecord == null}
         ref={(ref) => (ItemSelectRefs.current[index] = ref)}
      >
         {row.items.map((item: any) => {
            return (
               <option value={item.itemid} key={item.itemid}>
                  {item.item}
               </option>
            );
         })}
      </select>
   );
},


// This results in the following html
<select id="item-select-1" class="form-select form-select-sm">
   <option value="0">-</option>
   <option value="1">Item 1</option>
   <option value="2">Item 2</option>
</select>