Cara merender elemen setiap kali status diperbarui

Aug 21 2020

Saya mencoba membangun visualisator pengurutan menggunakan React. Saat ini saya mengimplementasikan bubbleort dan saya ingin melihat array saya di setiap tahap semacam itu.

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>
        )
    }

Mulanya:

Segera setelah mengklik "urutkan":

Meskipun saya menggunakan setState di dalam loop untuk setiap iterasi, saya hanya melihat array terurut terakhir. Saya ingin membuat array untuk setiap langkah pengurutan (dan mungkin menggunakan penundaan waktu). Tetapi saya tidak dapat menerapkan ini.
Adakah yang bisa membantu tentang cara memodifikasi kode ini untuk menerapkan fungsi seperti itu ... Terima kasih

Jawaban

2 yash Aug 21 2020 at 20:12

Oh, itu benar-benar berubah (Waktu eksekusi sangat cepat untuk dideteksi oleh mata) dan Anda akan melihatnya jika Anda menyetel beberapa penundaan dalam loop Anda.

Sebagai contoh:

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 })
        }
    }
}