2

I tried everything to make this inmutable without success:

The array that will change:

const [answers, setAnswers] = useState([]);

A button that runs my loop

onClick={ async() => my function}

A function that runs N requests, one by one and updates the answers matrix:

const myFunction = async () => { 

var results = [] 
for (let url of listOfUrls) {

try { answer = await apiCall(url)
results= [...results].concat(answer);
setAnswers(results);
 } catch (err) {}
} }

Problem: I'm updating var result

Request: Try to do this without using a var result

My try:

const myFunction = async () => { 
//naively cleaning my answers on each button click
setAnswers([])

//and then starting the loop
for (let url of listOfUrls) {

try { 
answer = await apiCall(url)
setAnswers([...answers].concat(answer));
 } catch (err) {}
} }

Result of my try: If "Answers" wasn't empty at the beginning of the process, even if i clean it using setAnswers([]) the following use of "answers" gets the old value, and then add the old requests to the new ones. They stack indefinitely

Working example: https://codesandbox.io/s/funny-smoke-l9sf2?file=/src/App.js

Loïc V
  • 517
  • 7
  • 9

1 Answers1

1

You want to use a functional update:

setAnswers([])

for (let url of listOfUrls) {
  try { 
    const newAnswers = await apiCall(url)
    setAnswers(answers => answers.concat(newAnswers));
  } catch (err) {}
}

Notice that setAnswers(…) does not change the answers variable.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I will need to read more info about this because i don't get why is it working haha but it works like a charm! Thank you very much! – Loïc V Jun 16 '20 at 21:51
  • also @Bergi, do you know how to cancel that for? I've created an If() with another variables that will be activated when the cancel button is pressed. The variable updates but keeps being false inside the for so i can't stop the for on demand – Loïc V Jun 16 '20 at 22:16