Masalah pemprosesan kelompok mikrotask React18
P粉506963842
P粉506963842 2023-09-07 22:30:24
0
1
501

rreeee

Dalam versi React18, mengapa hanya satu pemaparan berlaku apabila mengklik kaedah handleClick方法会出现两次渲染,而点击handleClick2?

Saya mahu output kedua-dua kaedah adalah sama. Bolehkah sesiapa memberitahu saya mengapa mereka berbeza?

P粉506963842
P粉506963842

membalas semua(1)
P粉642920522

Saya akan menerangkan cara jujukan panggilan ini berbeza dan cara tingkah laku yang diperhatikan boleh berlaku.

Saya tidak dapat memberitahu anda dengan tepat bagaimana keadaan kemas kini React dalam kelompok secara dalaman, Saya hanya mengandaikan bahawa React mempunyai pengoptimuman kompleks yang tidak berkaitan dengan pembangun menggunakan React dan memerlukan pengetahuan mendalam tentang dalaman React dan mungkin juga berubah dari satu versi ke versi yang lain. (Sila betulkan saya.)

Perbezaan

Promise.resolve() 安排一个新的微任务,实际上相当于 window.queueMicrotask().

Fungsi

setState (mungkin) juga akan menjadualkan microtask baharu, Oleh itu panggilan balik mereka (PromisesetStatePromise dan

) dipanggil dalam fasa pelaksanaan yang sama.

Perbezaan antara dua varian ini ialah
  • handleClickA 中,在两个 updater 函数之间调用 setState2 cangkuk
  • sambil
  • handleClickB 中,两个 updaterFungsi dalam
  • semuanya akan dipanggil terus dalam urutan.

Contoh kod

Saya menulis semula kod anda sedikit untuk menggambarkan urutan panggilan dengan lebih baik:

const setState1 = setState;     
const setState2 = setState;
const update1 = updaterFunction; // c => c + 1
const update2 = updaterFunction; // c => c + 1

const handleClickA = () => {          
                                  // Scheduled functions:
    setState1( update1 );         // 1. --> [ update1 ]
    
    queueMicrotask(() => {        // 2. --> [ update1, setState2 ]
        setState2( update2 );     // 4. --> [ update2 ]
    });

    // update1();                 // 3. --> [ setState2 ]
    // setState2( update2 );      // 4. --> [ update2 ]
    // update2();                 // 5. --> []
};

const handleClickB = () => {
                                  // Scheduled functions:    
    queueMicrotask(() => {        // 1. --> [ setState2 ]
        setState2( update2 );     // 3. --> [ update2 ]
    });

    setState1( update1 );         // 2. --> [ setState2, update1 ]
    
    // setState2( update2 );      // 3. --> [ update1, update2 ]
    // update1();                 // 4. --> [ update2 ]
    // update2();                 // 5. --> []
};

Arahan urutan panggilan

Di sini saya terangkan urutan panggilan.

(FIFO

>):

handleClickA

// 0. --> []
- schedule update1 (setState1())  // 1. --> [ update1 ]
- schedule setState2              // 2. --> [ update1, setState2 ]
- invoke update1()                // 3. --> [ setState2 ]
- schedule update2 (setState2())  // 4. --> [ update2 ]
- invoke update2()                // 5. --> []
handleClickB

// 0. --> []
schedule setState2              // 1. --> [ setState2 ]
schedule update1 (setState1())  // 2. --> [ setState2, update1 ]
schedule update2 (setState2())  // 3. --> [ update1, update2 ]
invoke update1()                // 4. --> [ update2 ]
invoke update2()                // 5. --> []

Tafsiran peribadi

updaterSaya menganggap React cuba mengumpulkan semua

​​fungsi sedang beratur.

iaitu apabila hanya fungsi pengemas kini dipanggil, cuba sekumpulan mereka bersama-sama dan hanya kemas kini keadaan

akhir sekali.

setStateWalau bagaimanapun, jika fungsi baharu dipanggil, React boleh melengkapkan gelung kemas kini semasa dan memulakan kitaran pemaparan baharu sebelum memanggil fungsi pengemaskini代码> seterusnya.

Saya hanya boleh meneka mengapa ini dilakukan

  • Kerana setState baharu mungkin memecahkan kumpulan entah bagaimana, atau
  • Jika setState panggilan baharu dibuat secara rekursif, pemaparan seterusnya akan ditangguhkan terlalu banyak, atau
  • Orang React masih mengusahakan strategi pengoptimuman terbaik dan pertukaran mereka.
  • (...atau ini pepijat.)
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan