React - delay on visualization

南笙酒味 提交于 2020-06-29 03:52:06

问题


I am building a sorting visualization. I started with a simple bubble sort. When I sort a small array everything is fine and the visualization looks good no matter the speed, but when I visualize a large array there is a delay and the visualization seems to start a few steps ahead and not showing some of the first steps. Why is it happening?

This is my Code:

import React, { useContext, useState, useEffect } from 'react';

const NUMBER_OF_ELEMENTS = 10;

const DEFAULT_COLOR = 'black';
const COMPARE_COLOR = 'darkred';
const DONE_COLOR = 'green';

const SPEED = 150;

const randomIntFromInterval = (min, max) => {
    return Math.floor(Math.random() * (max - min + 1) + min);
}

const Dummy = () => {
    const [arr, setArr] = useState([]);
    const [numberOfElements, setNumberOfElements] = useState(NUMBER_OF_ELEMENTS);

    const timeout_id = [];

    useEffect(() => {
        generateArray();
    }, []);

    const reset = () => {
        resetColors();
        generateArray();
    }

    const generateArray = () => {
        const arr1 = [];
        for(let i = 0; i < numberOfElements; i++)
        {
            arr1[i] = randomIntFromInterval(5, 100);
        }
        console.log(arr1);
        setArr(arr1);
    }

    const resetColors = () => {
        const arrayBars = document.getElementsByClassName('array-bar');
        for(let i = 0; i < arrayBars.length; i++) {
            arrayBars[i].style.backgroundColor = DEFAULT_COLOR;
        }
    }

    const bubbleSort = (arr, n) => {
        let i, j, temp, swapped, delay = 1;
        for(i = 0; i < n - 1; i++) 
        {
            swapped = false;
            for(j = 0; j < n - i - 1; j++) 
            {
                createColor([j, j + 1], COMPARE_COLOR,  delay++);
                if(arr[j] > arr[j + 1]) 
                {
                    // swap arr[j] and arr[j+1] 
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    swapped = true;
                    createAnimation(j, j + 1, delay++);
                }
                createColor([j, j + 1], DEFAULT_COLOR, delay++);
            }
            createColor([n - i - 1], DONE_COLOR, delay++);

            // If no two elements were  
            // swapped by inner loop, then break 
            if(swapped === false) break;
        }

        const leftovers = [];
        for(let k = 0; k < n - i - 1; k++) {
            leftovers.push(k);
        }

        createColor(leftovers, DONE_COLOR, delay++);
    }

    const createAnimation = (one, two, delay) => {
        const arrayBars = document.getElementsByClassName('array-bar');
        const id = setTimeout(() => {
            const barOneHeight = arrayBars[one].style.height;
            const barTwoHeight = arrayBars[two].style.height;
            arrayBars[two].style.height = `${barOneHeight}`;
            arrayBars[one].style.height = `${barTwoHeight}`;
        }, SPEED * delay);
        timeout_id.push(id);
    }

    const createColor = (indexes, color, delay) => {
        const arrayBars = document.getElementsByClassName('array-bar');
        const id = setTimeout(() => {
            for(let i = 0; i < indexes.length; i++) {
                arrayBars[indexes[i]].style.backgroundColor = color;
            }
        }, SPEED * delay);
        timeout_id.push(id);
    }

    const handleSort = (arr) => {
        bubbleSort(arr, arr.length);
    }

    const handlerRange = (e) => {
        setNumberOfElements(e.target.value);
    }

    const stopTimeOuts =() => {
        for(let i = 0; i < timeout_id.length; i++) {
            clearTimeout(timeout_id[i]);
        }
    }

    return (
        <div>
            <div className="array-container">
                {arr.map((value, idx) => (
                    <div className="array-bar"
                         key={idx}
                         style={{
                            backgroundColor: DEFAULT_COLOR,
                            height: `${value}px`,
                            width: `${100 / arr.length}%`,
                            display: 'inline-block',
                            margin: '0 1px'
                         }}>
                    </div>
                ))}
            </div>

            <div className="buttons-container">
                <button onClick={() => handleSort(arr)}>Sort!</button>
                <button onClick={() => reset()}>Reset</button>
                <button onClick={() => stopTimeOuts()}>Stop!</button>
            </div>

            <div className="slider-container">
                1
                <input type="range" 
                       min="1" 
                       max="100" 
                       onChange={(e) => handlerRange(e)} 
                       className="slider" 
                       id="myRange" 
                />
                100
            </div>
            {numberOfElements}

        </div>
    );
}

export default Dummy;

EDIT: I don't know why but it seems that there are times that the delay occurs and there are times that it isn't. For now I still don't know why and how to handle this.


回答1:


Almost always when there are performance issues in React it has to do with component being rendered multiple times. Try to change useEffect like this:

useEffect(() => {
        generateArray();
}, [NUMBER_OF_ELEMENTS]);


来源:https://stackoverflow.com/questions/62408271/react-delay-on-visualization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!