Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

297
Views
React how to update ui after every loop iteration which changes state array?

I am working on this react component. I want it to modify an array using a loop and reflect the changes in the UI after each iteration. I also added some code to halt the program so that each iteration will be displayed for a short time.

As for the UI, I have the numbers in the array itself followed by a button to start the loop. It seems that after pressing the button, the ui just freezes and the array is displayed but only after the last iteration of the loop. I want the onscreen array to change after every loop iteration. I tried using this.forceUpdate() but it did not change anything. I also tried using the spread (...) operator for changing the state but that did not change anything either. The relevant code and the GitHub are pasted below. The code can be found in src/ChangingArray.js in the project files. Thanks in advance.

import React, { Component } from 'react'

export default class ChangingArray extends Component {
  constructor(props) {
    super(props);
    this.state = {
      array: [1, 2, 3]
    }

    this.modifyArray = this.modifyArray.bind(this);
  }

  modifyArray = () => {
    for (let i = 0; i < 15; i++) {
      let newArray = [];
      for (let j = 0; j < this.state.array.length; j++) {
        newArray[j] = this.state.array[j];
      }
      newArray[i % newArray.length] = i;
      this.setState({
        array: [...newArray],
      })
      this.forceUpdate();
      //Code to halt the program
      const date = Date.now();
      let currentDate = null;
      do {
        currentDate = Date.now();
      } while (currentDate - date < 250);
    }
  }

  render() {
    return (
      <div>
        {this.state.array}
        <button onClick={this.modifyArray}>modify</button>
      </div>
    )
  }
}

https://github.com/AntonM-248/longestPalindromicSubstringVisualizer

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

By doing

do {
        currentDate = Date.now();
      } while (currentDate - date < 250);
    

you are synchronously blocking the thread, so your UI will obviously freeze:

I'm not sure I grasped what you are trying to achieve, but if you want to block the execution of a loop for a while before going to the next cycle, you need to implement an async iterator, let me show you how:

    function makeAsyncArray(arr, delay) {
    return {
    [Symbol.asyncIterator]() {
      let i = 0;
      return {
        next() {
          const done = i === arr.length;
          const value = done ? undefined : arr[i];
          i++;
          return new Promise((res) =>
            setTimeout(() => res({ value, done }), delay)
          );
        },
        return() {
          // This will be reached if the consumer called 'break' or 'return' early in the loop.
          return { done: true };
        },
      };
    },
  };
}

This function returns a special object called Async Iterator , this kind of iterators can be iterated by using this syntax:

 for await (const el of arr) //do something

Every element returned by this Iterator is a Promise so it can be awaited inside an async function and that's what we need if we want to make delayed loops that wait for something before to proceed to go on with cyclle. In this example, I used just a delay with a setTimeout to yield and block the loop asynchronously for some time, but you can use this logic to resolve that Promise with any other async logic ( for example the result of a fetch request ).

This is a working React implementation of this logic:

const arr = makeAsyncArray([1, 2, 3, 4, 5,6,7,8,9,10], 1000);

export default function App() {
  const [data, setData] = useState([]);
  // Data array will be populated adding one element every 1000ms since we have initialized the async iterator to resolve after 1000ms
  useEffect(() => {
    (async () => {
      for await (const el of arr) {
        setData((d) => [...d, el]);
      }
    })();
  }, []);

  return <div>{data}</div>;
}


function makeAsyncArray(arr, delay) {
  return {
    [Symbol.asyncIterator]() {
      let i = 0;
      return {
        next() {
          const done = i === arr.length - 1;
          const value = done ? undefined : arr[i];
          i++;
          return new Promise((res) =>
            setTimeout(() => res({ value, done }), delay)
          );
        },
        return() {
          // This will be reached if the consumer called 'break' or 'return' early in the loop.
          return { done: true };
        },
      };
    },
  };
}

The live demo: https://stackblitz.com/edit/react-yie8pg

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!