<p>React-dnd kann eine nicht gemountete Komponente aufrufen, was zu `Uncaught Error: Konnte keine gültige Ziel-Id gefunden wurde`</p>

Erstellt am 2. Juni 2019  ·  3Kommentare  ·  Quelle: react-dnd/react-dnd

Beschreibe den Fehler
es ist für React-dnd möglich, eine Collect-Funktion aufzurufen, die das Aushängen einer Komponente bewirkt, und dann einen weiteren collect()-Aufruf für die nicht eingehängte Komponente auszuführen, was einen nicht abgefangenen Fehler "Keine gültige Ziel-ID konnte gefunden werden" verursacht.

Redux on it's dispatch() von Backend-Drag-and-Drop-Ereignissen erstellt zu Beginn eine Kopie aller Listener für abonnierte Ereignisse und ruft sie immer auf, unabhängig davon, welche Redux-Abonnements abgemeldet wurden, während die Abonnenten benachrichtigt werden (siehe https://stackoverflow.com/questions /43356080/redux-unsubscribe-within-componentwillunmount-still-calls-subscribe-callback). Dies bedeutet, dass, wenn so etwas wie ein 'EndDrag'-HTML5-Drag-Ereignis eine Benachrichtigung in handleChange() in React-dnd/src/decorateHandler.tsx:handleChange() auslöst und der erste Aufruf von collect() ein Unmounten einer Komponente bewirkt, die nachfolgende nicht gemountete Komponente kann ihren collect()-Aufruf in einer nachfolgenden Benachrichtigung über dasselbe Ereignis auslösen.

Somit wird die Invariante 'Es wird erwartet, dass ein gültiges Ziel gefunden wird' ausgelöst, weil die Komponente gültig aus der Registrierung gültiger Ziel-IDs entfernt wurde, aber die Benachrichtigung eine nicht gemountete Komponente aufruft.

Ich habe dieses Problem entdeckt, als ich versuchte, "react-sortable-tree" zu integrieren, das "react-dnd" in meine App verwendet. Ein Beispiel für das Problem und einen nachstellbaren Testfall finden Sie hier: https://github.com/frontend-collective/react-sortable-tree/issues/490. Ein Ziehen und Ablegen, das abgebrochen wird, indem eine DragSource außerhalb des dragTarget freigegeben wird, reproduziert dieses Problem jedes Mal.

Der nicht abgefangene Fehler und der Stack-Trace werden unten eingefügt. Der Stack-Trace zeigt, dass die Verbindungsfunktion monitor.canDrop() aufruft, was bei nicht gemounteten Komponenten fehlschlägt.
browser.js:38 Nicht abgefangener unveränderlicher Verstoß: Es wird erwartet, dass ein gültiges Ziel gefunden wird.bei invariant (https://xzoq6xprlz.codesandbox.io/node_modules/invariant/browser.js:38:15)bei DragDropMonitorImpl.canDropOnTarget (https://xzoq6xprlz.codesandbox.io/node_modules/dnd-core/lib/cjs/DragDropMonitorImpl.js:67:9)
bei DropTargetMonitorImpl.canDrop (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd/lib/cjs/DropTargetMonitorImpl.js:24:41)
bei nodeDropTargetPropInjection (https://xzoq6xprlz.codesandbox.io/node_modules/react-sortable-tree/dist/index.cjs.js:2367:28)
bei DragDropContainer.getCurrentState (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd/lib/cjs/decorateHandler.js:116:29)
bei DragDropContainer._this.handleChange (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd/lib/cjs/decorateHandler.js:45:39)
bei handleChange (https://xzoq6xprlz.codesandbox.io/node_modules/dnd-core/lib/cjs/DragDropMonitorImpl.js:27:21)
beim Versand (https://xzoq6xprlz.codesandbox.io/node_modules/redux/lib/redux.js:220:7)
at Object.eval [as endDrag] (https://xzoq6xprlz.codesandbox.io/node_modules/dnd-core/lib/cjs/DragDropManagerImpl.js:67:21)
bei HTML5Backend.handleTopDragEndCapture (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd-html5-backend/lib/cjs/HTML5Backend.js:145:31)
``

Problemumgehung

Das Aufrufen von nicht gemounteten Komponenten ist wahrscheinlich nicht das richtige Verhalten, daher habe ich eine if-Anweisung in response-dnd/src/decorateHandler.tsx:handleChange hinzugefügt, die die Benachrichtigung verwirft, wenn der decorHandler bereits abgemeldet wurde. div beigefügt.

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

Hilfreichster Kommentar

@mx2323 wurde das eingeschoben? Auch wenn es der React-Sortable-Tree war, der immer noch die neuesten React-Dnd-Updates benötigt, denke ich, dass er wartet

Alle 3 Kommentare

Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivität hatte. Es wird geschlossen, wenn keine weitere Aktivität stattfindet. Vielen Dank für Ihre Beiträge.

@mx2323 wurde das eingeschoben? Auch wenn es der React-Sortable-Tree war, der immer noch die neuesten React-Dnd-Updates benötigt, denke ich, dass er wartet

Ich habe es am Ende nicht gedrückt.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen