Come rendere l'elemento ogni volta che lo stato viene aggiornato

Aug 21 2020

Sto cercando di creare un visualizzatore di ordinamento usando React. In questo momento sto implementando BubbleSort e voglio vedere il mio array in ogni fase dell'ordinamento.

class Sorter extends Component {
    state = {
          array: [100,4,214,55,11,22,10,33],
    }
     bubblesorter = () => {
        let arr = this.state.array
        var len = arr.length,
        i, j, stop;
            for (i=0; i < len; i++){
                    for (j=0, stop=len-i; j < stop; j++){
                        if (arr[j] > arr[j+1]){
                            swap(arr, j, j+1);
                        } 
                        this.setState({array:arr})
                    }
                }   
    }

    render() {
        const array = this.state.array
        // console.log(array)
        return (
            <div>
                <h1>This is a sorter</h1>
                <div className="container">
                    {array.map((value, id) => (
                        <span>
                            <div className="bar" key={id} style={{height: value+"px"}}  >
                            </div>
                        </span>
                    ))}
                </div>
                <button onClick={this.bubblesorter}>Sort</button>
            </div>
        )
    }

Inizialmente:

Subito dopo aver fatto clic su "ordina":

Anche se sto usando setState all'interno del ciclo per ogni iterazione, vedo solo l'array ordinato finale. Vorrei eseguire il rendering dell'array per ogni fase dell'ordinamento (e possibilmente utilizzando un ritardo). Ma non sono in grado di implementarlo.
Qualcuno può aiutare su come modificare questo codice per implementare tale funzionalità ... Grazie

Risposte

2 yash Aug 21 2020 at 20:12

Oh, in realtà cambia (il tempo di esecuzione è così veloce da rilevare per gli occhi) e lo vedrai se imposti un certo ritardo nel tuo ciclo.

Per esempio:

bubblesorter = async () => {
    let arr = this.state.array
    var len = arr.length,
        i, j, stop;
    for (i = 0; i < len; i++) {
        for (j = 0, stop = len - i; j < stop; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr, j, j + 1);
            }
            // Added 1 second delay here.
            await new Promise(resolve => setTimeout(resolve, 1000));
            this.setState({ array: arr })
        }
    }
}