0

I'm trying to run a for loop in a React app which will run through a user defined range of tokens and place bids based on i of the for loop. Sounds very simple, and it is.

However I'm having an issue where I've added a block to check whether "isBidding" changes to false, which should then break the for loop. isBidding is a state variable local to the component.

It seems like when the for loop starts, isBidding will always be true, even when the state is changed to false whilst the loop is running. I can't for the life of me figure out how to ensure the global state variable isBidding gets updated within a for loop.

for (let i = startTokenId; i < endTokenId + 1; i++) {
  // Inside the loop we try to place bids on each token, waiting for user action
  setBidderScanningString(`Bidding on token id #${i} (${i} of ${endTokenId})...`);
  // Try to place the bid
  try {
    await createBuyOrder(i);
  } catch (e) {
    parseBidError(e);
  }
  // Check if loop is over, if so set bidding to false and end
  if (i.toString().toLowerCase() === endTokenId.toString().toLowerCase()) {
    setBidderScanningString('Bidding finished...');
    setIsBidding(false);
    return;
  }
  // Check whether isBidding has been set to false
  if (!isBidding) {
     return;
  }
}

From within the loop I have tried to call a function, which returns the latest isBidding state, however this always evaluates to true.

I have tried to add isBidding in the 2nd condition of the for loop however it still always evaluates to true. I have also tried to add labels and nest it inside a while (isBidding) loop however it still always evaluates to true.

I have also tried moving this code into a useEffect with a dependency on isBidding however the for loop still always returns true.

Is there something blindingly obvious I'm missing?

1 Answers1

0

It seems that you are using useState setter setIsBidding and getter isBidding. JavaScript is single-threaded, and the for-loop runs synchronously, which just means that the entire loop will finish before the effects of calling setIsBidding are reflected in isBidding.

I would suggesting declaring a value locally for use inside the for loop, and then after the loop is done you can save the value to setIsBidding if desired.

msenne
  • 613
  • 5
  • 8