<p>react-dnd dapat memanggil komponen yang tidak di-mount yang menyebabkan `Kesalahan Tidak Tertangkap: Tidak dapat menemukan targetId yang valid`</p>

Dibuat pada 2 Jun 2019  ·  3Komentar  ·  Sumber: react-dnd/react-dnd

Jelaskan bugnya
mungkin untuk react-dnd untuk memanggil fungsi kumpulkan yang menyebabkan komponen dilepas, lalu buat panggilan collect() lain pada komponen yang tidak dipasang, menyebabkan Kesalahan Tidak Tertangkap "Tidak dapat menemukan targetId yang valid'.

Redux pada pengirimannya () dari acara Drag And Drop backend membuat salinan semua pendengar ke acara berlangganan di awal dan selalu memanggil mereka terlepas dari langganan redux apa yang telah berhenti berlangganan saat memberi tahu pelanggan (lihat https://stackoverflow.com/questions /43356080/redux-unsubscribe-within-componentwillunmount-still-calls-subscribe-callback). Ini berarti bahwa jika sesuatu seperti peristiwa seret html5 'EndDrag' memicu pemberitahuan di handleChange() di react-dnd/src/decorateHandler.tsx:handleChange(), dan panggilan collect() pertama menyebabkan pelepasan komponen, komponen unmount berikutnya mungkin memiliki panggilan collect() yang dipicu dalam pemberitahuan berikutnya dari peristiwa yang sama.

Dengan demikian, invarian 'Diharapkan menemukan target yang valid' dipicu karena komponen secara valid telah dihapus dari registri ID target yang valid, tetapi notifikasi memanggil komponen yang tidak di-mount.

Saya menemukan masalah ini ketika mencoba mengintegrasikan react-sortable-tree, yang menggunakan react-dnd ke dalam aplikasi saya. Anda dapat melihat contoh masalah dan kasus uji yang dapat dibuat ulang di sini: https://github.com/frontend-collective/react-sortable-tree/issues/490. Seret dan lepas yang dibatalkan dengan melepaskan dragSource di luar dragTarget mereproduksi masalah ini setiap saat.

Kesalahan yang tidak tertangkap dan jejak tumpukan ditempelkan di bawah, Jejak tumpukan menunjukkan bahwa fungsi koneksi memanggil ke monitor.canDrop() yang gagal pada komponen yang dilepas.
browser.js:38 Pelanggaran Invarian Tidak Tertangkap: Diharapkan menemukan target yang valid.di invarian (https://xzoq6xprlz.codesandbox.io/node_modules/invariant/browser.js:38:15)di DragDropMonitorImpl.canDropOnTarget (https://xzoq6xprlz.codesandbox.io/node_modules/dnd-core/lib/cjs/DragDropMonitorImpl.js:67:9)
di DropTargetMonitorImpl.canDrop (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd/lib/cjs/DropTargetMonitorImpl.js:24:41)
di nodeDropTargetPropInjection (https://xzoq6xprlz.codesandbox.io/node_modules/react-sortable-tree/dist/index.cjs.js:2367:28)
di DragDropContainer.getCurrentState (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd/lib/cjs/decorateHandler.js:116:29)
di DragDropContainer._this.handleChange (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd/lib/cjs/decorateHandler.js:45:39)
di handleChange (https://xzoq6xprlz.codesandbox.io/node_modules/dnd-core/lib/cjs/DragDropMonitorImpl.js:27:21)
saat pengiriman (https://xzoq6xprlz.codesandbox.io/node_modules/redux/lib/redux.js:220:7)
di Object.eval [sebagai endDrag] (https://xzoq6xprlz.codesandbox.io/node_modules/dnd-core/lib/cjs/DragDropManagerImpl.js:67:21)
di HTML5Backend.handleTopDragEndCapture (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd-html5-backend/lib/cjs/HTML5Backend.js:145:31)
``

Solusi

Memanggil ke komponen yang tidak di-mount mungkin bukan perilaku yang benar, jadi saya menambahkan pernyataan if di react-dnd/src/decorateHandler.tsx:handleChange yang menghapus pemberitahuan jika decorHandler telah berhenti berlangganan. perbedaan terpasang.

diff --git a/packages/react-dnd/src/decorateHandler.tsx b/packages/react-dnd/src/decorateHandler.tsx
index 85385ec..bcd149e 100644
--- a/packages/react-dnd/src/decorateHandler.tsx
+++ b/packages/react-dnd/src/decorateHandler.tsx
@@ -159,6 +159,15 @@ export default function decorateHandler<Props, CollectedProps, ItemIdType>({
                }

                public handleChange = () => {
+                       if (this.disposable.isDisposed) {
+                               console.log("in handleChange")
+                               //because redux takes a snapshot of all subscribers to 
+                               //events when it starts dispatch, it is still possible to call into this even after 
+                               //the subscription has been unsubscribed
+                               //to prevent against calling into unmounted objects, return immediately
+
+                               return
+                       }
                        const nextState = this.getCurrentState()
                        if (!shallowEqual(nextState, this.state)) {
                                this.setState(nextState)
wontfix

Komentar yang paling membantu

@ mx2323 apakah ini didorong? Bahkan jika itu adalah pohon reaksi-sortable masih membutuhkan pembaruan reaksi-dnd terbaru, saya pikir itu sedang menunggu

Semua 3 komentar

Masalah ini secara otomatis ditandai sebagai basi karena tidak ada aktivitas terbaru. Ini akan ditutup jika tidak ada aktivitas lebih lanjut yang terjadi. Terima kasih atas kontribusi Anda.

@ mx2323 apakah ini didorong? Bahkan jika itu adalah pohon reaksi-sortable masih membutuhkan pembaruan reaksi-dnd terbaru, saya pikir itu sedang menunggu

saya tidak akhirnya mendorongnya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat