Home > Software engineering >  React, timed loop updating DOM at once instead of updating in increments
React, timed loop updating DOM at once instead of updating in increments

Time:11-08

I am trying to visualize the Bubblesort algorithm using react.

New to react, help appreciated - I saw similar questions but couldn't get it to work

in my main app.jsx i have following code setup to create the necessary DOM elements:

...
let test_arr = [10, 4, 30, 7, 15, 5, 30, 6];

return (
    <div className="sorting_container">
         {test_arr.map((num, index) => (
             <DataBlock val={num} pos={index} key={index} />
         ))}
    </div>
);
...

The corresponding DataBlock.jsx component:

import React from "react";

class DataBlock extends React.Component {
    constructor(props) {
        super(props);

        this.height_multiplier = 3.5;
        this.position_multiplier = 42;
    }

    render() {
        return(
            <div id={`DataBlock${this.props.pos}`} className="DataBlock"
                style={{
                    height: `${ this.height_multiplier * parseInt(this.props.val) }px`,
                    transform: `translateX(${ parseInt(this.props.pos) * this.position_multiplier }px)`
                }}
            >
                <label>{this.props.val}</label>
            </div>
        );
    }
}

export { DataBlock };

using the above code I am able to generate my desired output: enter image description here

To simplify what I want: To visualize the algorithm I need to be able to change the styles of each DataBlock element. To show you my problem I simplified the procedure by just changing each DataBlock's backgroundColor to red - in increments of 1 at a time and a pause of 1s between each change.

To achieve that I use "useEffect", inside my app.jsx, to call BubbleSort.jsx.

...
useEffect(() => {
        BubbleSort();
});
...

My BubbleSort.jsx file:

function BubbleSort() {
    let datablocks = document.getElementsByClassName("DataBlock");

    for(let i=0;i<datablocks.length;i  ) {
        setTimeout(() => {
            document.getElementById(`DataBlock${i}`).style.backgroundColor = "red";
        }, 1000)
    }
}

export default BubbleSort;

The code changes all the elements from green background to red at once after 1s. I expect it to change each element seperately with 1s pauses. How can I achieve that or is my approach wrong from the beginning?

CodePudding user response:

You have to timeout the for loop. You can achieve this with i * 1000 delay in timeout. Try this;

function BubbleSort() {
    let datablocks = document.getElementsByClassName("DataBlock");

    for(let i=0;i<datablocks.length;i  ) {
        setTimeout(() => {
            document.getElementById(`DataBlock${i}`).style.backgroundColor = "red";
        }, i * 1000)
    }
}

export default BubbleSort;
  • Related