React-dnd: Peringatan Dengan DragSource Bersarang

Dibuat pada 6 Apr 2016  ·  27Komentar  ·  Sumber: react-dnd/react-dnd

Jika Anda memiliki DragSource di dalam komponen yang juga merupakan DragSource (yaitu menyeret sesuatu ke dalam draggable), setiap kali komponen induk ditarik, peringatan berikut akan muncul.

Warning: setState(...): Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.
warning @   modules.js?hash=107dc56…:19491
getInternalInstanceReadyForUpdate   @   modules.js?hash=107dc56…:5476
ReactUpdateQueue.enqueueSetState    @   modules.js?hash=107dc56…:5617
ReactComponent.setState @   modules.js?hash=107dc56…:15132
handleChange    @   modules.js?hash=107dc56…:20844
handleChange    @   modules.js?hash=107dc56…:22861
dispatch    @   modules.js?hash=107dc56…:23568
addSource   @   modules.js?hash=107dc56…:23124
registerSource  @   modules.js?hash=107dc56…:21172
receiveType @   modules.js?hash=107dc56…:21099
receiveProps    @   modules.js?hash=107dc56…:21089
DragSource(NestedComponent) @   modules.js?hash=107dc56…:21062
ReactCompositeComponentMixin.mountComponent @   modules.js?hash=107dc56…:6679
ReactCompositeComponent_mountComponent  @   modules.js?hash=107dc56…:896
ReactReconciler.mountComponent  @   modules.js?hash=107dc56…:5167
ReactMultiChild.Mixin.mountChildren @   modules.js?hash=107dc56…:13562
ReactDOMComponent.Mixin._createContentMarkup    @   modules.js?hash=107dc56…:10901
ReactDOMComponent.Mixin.mountComponent  @   modules.js?hash=107dc56…:10789
ReactReconciler.mountComponent  @   modules.js?hash=107dc56…:5167
ReactCompositeComponentMixin._updateRenderedComponent   @   modules.js?hash=107dc56…:7101
ReactCompositeComponentMixin._performComponentUpdate    @   modules.js?hash=107dc56…:7075
ReactCompositeComponentMixin.updateComponent    @   modules.js?hash=107dc56…:7004
ReactCompositeComponent_updateComponent @   modules.js?hash=107dc56…:896
ReactCompositeComponentMixin.receiveComponent   @   modules.js?hash=107dc56…:6936
ReactReconciler.receiveComponent    @   modules.js?hash=107dc56…:5217
ReactCompositeComponentMixin._updateRenderedComponent   @   modules.js?hash=107dc56…:7093
ReactCompositeComponentMixin._performComponentUpdate    @   modules.js?hash=107dc56…:7075
ReactCompositeComponentMixin.updateComponent    @   modules.js?hash=107dc56…:7004
ReactCompositeComponent_updateComponent @   modules.js?hash=107dc56…:896
ReactCompositeComponentMixin.receiveComponent   @   modules.js?hash=107dc56…:6936
ReactReconciler.receiveComponent    @   modules.js?hash=107dc56…:5217
ReactCompositeComponentMixin._updateRenderedComponent   @   modules.js?hash=107dc56…:7093
ReactCompositeComponentMixin._performComponentUpdate    @   modules.js?hash=107dc56…:7075
ReactCompositeComponentMixin.updateComponent    @   modules.js?hash=107dc56…:7004
ReactCompositeComponent_updateComponent @   modules.js?hash=107dc56…:896
ReactCompositeComponentMixin.performUpdateIfNecessary   @   modules.js?hash=107dc56…:6952
ReactReconciler.performUpdateIfNecessary    @   modules.js?hash=107dc56…:5232
runBatchedUpdates   @   modules.js?hash=107dc56…:5832
Mixin.perform   @   modules.js?hash=107dc56…:6304
Mixin.perform   @   modules.js?hash=107dc56…:6304
assign.perform  @   modules.js?hash=107dc56…:5789
flushBatchedUpdates @   modules.js?hash=107dc56…:5850
ReactUpdates_flushBatchedUpdates    @   modules.js?hash=107dc56…:896
Mixin.closeAll  @   modules.js?hash=107dc56…:6370
Mixin.perform   @   modules.js?hash=107dc56…:6317
ReactDefaultBatchingStrategy.batchedUpdates @   modules.js?hash=107dc56…:10295
enqueueUpdate   @   modules.js?hash=107dc56…:5879
enqueueUpdate   @   modules.js?hash=107dc56…:5460
ReactUpdateQueue.enqueueSetState    @   modules.js?hash=107dc56…:5626
ReactComponent.setState @   modules.js?hash=107dc56…:15132
handleChange    @   modules.js?hash=107dc56…:21121
handleChange    @   modules.js?hash=107dc56…:22861
dispatch    @   modules.js?hash=107dc56…:23568
(anonymous function)    @   modules.js?hash=107dc56…:22100
endDragIfSourceWasRemovedFromDOM    @   modules.js?hash=107dc56…:29563
handleTopDrop   @   modules.js?hash=107dc56…:29860

Contohnya adalah:

class ParentDraggable extends React.Component {
    render() {
        return this.props.connectDragSource(
            <NestedDraggable/>
        );
    }
}

//... Skip the code for containers

class NestedDraggable extends React.Component {
    render() {
        return this.props.connectDragSource(
            <div></div>
        );
    }
}

Saya yakin masalah ini berasal dari fakta bahwa merender ulang komponen induk menyebabkan panggilan DragSource anak membuat panggilan ke setState selama pemanggilan fungsi acceptProps?

triage wontfix

Komentar yang paling membantu

Untuk berjaga-jaga jika itu membantu seseorang: Saya mengalami ini ketika saya merender komponen yang merupakan sumber seret di lapisan seret khusus saya karena nyaman. Saya menggunakan komponen sumber seret karena itu adalah entitas yang sama yang saya coba seret, jadi masuk akal bagi saya untuk menyimpan kode "KERING" dengan menggunakannya kembali. Saya tidak berpikir tentang fakta bahwa ia memiliki semua kode dragSource di dalamnya - melihat ke belakang, _of course_ Saya tidak ingin sumber drag SEBAGAI hal untuk dirender di lapisan drag kustom.

Saya akhirnya membagi komponen saya menjadi versi "Draggable" yang membungkus komponen dasar, dan kemudian menggunakan komponen dasar di lapisan seret kustom saya. Tidak ada peringatan lagi, kode yang lebih baik! 👍

Semua 27 komentar

: +1:

Bisakah Anda memberikan proyek yang mereproduksi masalah?

Saya mencoba membuat contoh sederhana dan saya mengalami masalah mereproduksi di luar proyek pribadi saya yang sedang saya kerjakan. @nihtalak , apakah Anda memiliki repo di Github yang menghasilkan masalah tersebut?

Ini repo kecil yang menunjukkan perilaku yang dijelaskan: https://github.com/ebakan/react-dnd-nested-bug

Anehnya, Component hanya memunculkan kesalahan ini ketika mendengarkan monitor.getItem() . Jika mendengarkan monitor.isDragging() itu akan berfungsi dengan baik, seperti yang ditunjukkan di cabang ini: https://github.com/ebakan/react-dnd-nested-bug/tree/no-error-with-is- seret

Ini juga akan memunculkan kesalahan saat mendengarkan monitor.getItemType() : https://github.com/ebakan/react-dnd-nested-bug/tree/error-with-get-item-type

@ebakan - menarik. Saya bertanya-tanya apa yang menyebabkan bug ini muncul di kode saya, yang menggunakan isDragging. Saya melakukan beberapa hal miring dengan draggable bersarang, jadi ini bisa menjadi manifestasi dari bug yang sama yang Anda lihat. Terima kasih atas bantuannya untuk mereproduksi!

Saya juga memiliki draggable bersarang, tetapi tidak yakin apakah itu masalahnya.
Tampaknya akan membuat toko baru dan kode yang mendengarkan. Saya membuat video jika itu membantu:
http://screencast.com/t/qCrJRPAS2MYR

Pembaruan: menemukan masalah, saya memiliki pendengar yang tersisa jadi dalam kasus saya itu bukan karena react-dnd.
Pembaruan2: Saya berbicara terlalu cepat. Setelah menghapus pendengar yang tersisa, saya masih mendapatkan peringatan.

Saya baru saja menambahkan Dnd ke komponen lain dan melihat masalah ini bahkan tanpa komponen bersarang atau beberapa menyeret.

Setelah sedikit menggali, saya menemukan bahwa masalah tersebut terkait dengan lapisan seret khusus yang merender komponen saat diseret.

Jika saya meletakkan teks, bukan komponen yang diseret, itu berfungsi dengan baik. Komponen itu sendiri adalah sumber seret.

@jchristman @hakunin Saya tidak memiliki draggable bersarang, tetapi menemukan Cannot update during an existing state transition ketika saya memiliki target penurunan yang dirender secara bersyarat berdasarkan isDragging . Mungkinkah ini kasusnya di salah satu contoh Anda? Sesuatu seperti ini:

render() {
    var dropZone;
    if (this.props.isDragging) dropZone = <MyDropTarget />;
    return <div>
       <MyDragSource />
       {dropZone}
    </div>
}

Akhirnya menyelesaikannya dengan menggunakan display: none/block untuk menyembunyikan target daripada menambah dan menghapus komponen saat menyeret aktif.

Saya pikir itu bisa menjadi masalahnya. Saya akan memeriksa dan memberi tahu Anda. Itu pasti konstruksi yang saya gunakan sekarang.

Tidak - Saya mendapatkan masalah saat "jatuh" terjadi. Kemudian ia mencoba untuk merender ulang komponen dan melontarkan peringatan ini.

Mendapat peringatan yang sama ketika pratinjau seret saya adalah komponen yang merupakan DragSource (yang seharusnya tidak saya lakukan).

@jchristman pernahkah Anda menemukan solusi untuk ini?

Saya bekerja dengan dragSources bersarang dan tiba-tiba mulai melihat kesalahan ini saat melepaskan resource bersarang.

Saya dapat memberikan contoh tetapi ingin melihat apakah ada yang telah memecahkan masalah tersebut, atau memiliki solusi yang sesuai.

Mendapat peringatan yang sama ketika pratinjau seret saya adalah komponen yang merupakan DragSource (yang seharusnya tidak saya lakukan).

Terima kasih @arjunu , peringatan saya disebabkan oleh ini!
Saya masih memiliki ini sesekali jadi saya kira ada alasan lain yang harus diperbaiki juga. Mungkin ada di pihak saya :)

@ gharwood1 , saya hanya akan membahas masalah ini sampai masalah tersebut dapat diperbaiki. Saya menghabiskan beberapa jam sekali mencoba untuk benar-benar memahami perpustakaan ini sehingga saya dapat menarik permintaan perbaikan tetapi itu cukup rumit, jadi saya melanjutkan. Saya hanya tidak punya waktu ... :-(

@gaearon Saya tidak cukup memiliki proyek yang dibuat yang mampu membuat seseorang merobohkan, tapi saya pikir saya bisa membuatnya jika diperlukan.

Pada dasarnya, apa yang saya coba lakukan di sini valid:

https://github.com/arackaf/booklist/blob/react-dnd-bug-freeze/react-redux/modules/subjects/components/subjectsList-es6.js

Jika saya menonaktifkan kondisional di baris 64 semuanya baik-baik saja

if (this.props.draggingSubject){
    effectiveChildren.push(this.props.draggingSubject);
}

namun begitu hasil dari peristiwa tarik mulai mengubah alat peraga dan rendering komponen, peringatan di atas mulai sering dimuntahkan.

Haruskah saya tidak melakukan ini?

Kasus penggunaan pada dasarnya adalah untuk "melihat" item yang saat ini diseret di target pelepasan. Di atas adalah bukti konsep - belum terhubung ke toko Redux, karena saya tidak yakin apakah ini valid.


Hm, sepertinya tidak apa-apa jika saya menyimpan perubahan saya lokal ke SubjectDisplayContent , tetapi peringatan mulai terjadi jika perubahan meluas ke SubjectDisplay . Jadi pada dasarnya, jika dropTarget mengirim props ke bawah yang mengubah dropTarget berbeda , react-dnd akan terganggu. Apakah ini diharapkan, dan saya perlu memikirkan kembali beberapa hal, atau apakah ini bug dengan dnd?

Saya mengalami masalah yang persis sama. Apa yang dapat Anda lakukan dalam beberapa situasi adalah membuat DragDropContext sekitar setiap draggable bersarang. Tetapi ini tidak berfungsi segera jika Anda menginginkan DragLayer kustom ..

Saya mendapat kesalahan yang sama, kecuali saya melakukan dropTarget bersarang.
Setelah melihat-lihat dokumentasi, saya mencoba menggunakan

isOver (options): Mengembalikan nilai true jika ada operasi seret yang sedang berlangsung, dan penunjuk saat ini melayang di atas pemilik. Secara opsional, Anda dapat meneruskan {shallow: true} untuk memeriksa secara ketat apakah hanya pemilik yang di-hover, sebagai lawan dari target bertingkat.

(dengan opsi shallow is true) di fungsi canDrop dari dropTarget induk, dan masalahnya hilang. Saya akan berpikir hal yang sama dapat diterapkan pada beberapa skenario lain.

@jchenjc Saya mencoba ini tetapi tidak berhasil untuk saya. Sejujurnya situasi saya sangat rumit dengan pratinjau seret bersarang + sumber seret + target lepas yang perlu bekerja di seluruh daftar.

FWIW: Saya memiliki sumber seret bersarang dan lapisan seret khusus. Saat saya menghapus lapisan seret khusus, pesan tersebut hilang. Dari pemeriksaan pelacakan tumpukan, sepertinya masalahnya ada di sini:

printWarning    @   warning.js?8a56:36
warning @   warning.js?8a56:60
getInternalInstanceReadyForUpdate   @   ReactUpdateQueue.js?6531:54
enqueueSetState @   ReactUpdateQueue.js?6531:200
ReactComponent.setState @   ReactComponent.js?702a:63
handleChange    @   DragLayer.js?1cbc:124 <--------------
handleChange    @   DragDropMonitor.js?0588:60

Kode yang relevan ada di sini . Saya akan melihat mengapa keadaan mungkin berbeda dalam kasus saya untuk memicu render ulang ...

Dengan dragsource + droptarget bersarang di dalam droptarget, saya mendapatkan masalah ini.

Sebagian dari alasan ini terjadi adalah karena gaearon membayangkan melakukan drag and drop daftar dengan menjadikan setiap item daftar sebagai target pelepasan, daripada menjadikan komponen daftar sebagai target penurunan tunggal yang menentukan apa yang harus dilakukan berdasarkan posisi drag hover. Cara terakhir adalah bagaimana kebanyakan sistem DnD lain yang pernah saya lihat melakukan sesuatu.

Untuk berjaga-jaga jika itu membantu seseorang: Saya mengalami ini ketika saya merender komponen yang merupakan sumber seret di lapisan seret khusus saya karena nyaman. Saya menggunakan komponen sumber seret karena itu adalah entitas yang sama yang saya coba seret, jadi masuk akal bagi saya untuk menyimpan kode "KERING" dengan menggunakannya kembali. Saya tidak berpikir tentang fakta bahwa ia memiliki semua kode dragSource di dalamnya - melihat ke belakang, _of course_ Saya tidak ingin sumber drag SEBAGAI hal untuk dirender di lapisan drag kustom.

Saya akhirnya membagi komponen saya menjadi versi "Draggable" yang membungkus komponen dasar, dan kemudian menggunakan komponen dasar di lapisan seret kustom saya. Tidak ada peringatan lagi, kode yang lebih baik! 👍

@davidjoy woah , terima kasih sudah berbagi! Saya melakukan hal yang sama, perlu mencobanya juga!

@davidjoy Baru saja memperbaiki milikku juga. Saran Anda menunjukkan untuk tidak menggunakan DragSource dan semacamnya untuk lapisan khusus. Apa yang saya lakukan hanyalah menggunakan komponen telanjang tanpa DragSource di lapisan seret khusus saya dan itu berhasil.

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

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

user1736 picture user1736  ·  3Komentar

gocreating picture gocreating  ·  4Komentar

redochka picture redochka  ·  3Komentar

antoineBernard picture antoineBernard  ·  3Komentar

bebbi picture bebbi  ·  3Komentar