Hallo Dan,
Nur eine kurze - ich versuche, meine eigene Komponente mit react-dnd
als Abhängigkeit in einer anderen App zu verwenden, die selbst react-dnd
sodass der oben genannte Fehler erwartet wird. Was wäre in diesem Fall der beste Weg, dies zu beheben?
Da die andere Komponente meine eigene ist, kann ich den Aufruf von DragDropContext
beim Exportieren der Komponente entfernen, was jedoch die Wiederverwendbarkeit der Komponente beeinträchtigt. Was raten Sie?
Überprüfen Sie die Quelle für DragDropContext . Ich denke, Sie sollten in der Lage sein, den vorhandenen Manager wiederzuverwenden, wenn er von einer Komponente über dem Baum angegeben wird. Aber es ist immer noch eine knifflige Frage. Haben Sie Lösungsvorschläge?
Ich denke, Sie sollten in der Lage sein, den vorhandenen Manager wiederzuverwenden, wenn er von einer Komponente über dem Baum angegeben wird.
Selbst wenn dies möglich ist, sollte die exportierte Komponente auch unabhängig arbeiten können. In Fällen, in denen das Backend vorhanden ist (in der App, in der die Komponente verwendet wird), sollte irgendwo in der Kette wiederverwendet werden. Ich werde versuchen, die Quelle zu lesen und zu sehen, ob dies durchgeführt werden kann.
Leider besteht die einzige Lösung, die mir derzeit einfällt, darin, die endgültige Komponente so zu exportieren, wie sie ist, und vom Benutzer zu erwarten, dass er ein DragDropContext
mit einem Backend seiner Wahl hinzufügt. Was denken Sie?
Die exportierte Komponente sollte auch unabhängig arbeiten können. In Fällen, in denen das Backend vorhanden ist (in der App, in der die Komponente verwendet wird), sollte irgendwo in der Kette wiederverwendet werden.
Ja, dies ist möglich, indem Sie DragDropContext
insgesamt verwenden und stattdessen manuell dragDropManager
im Kontext verwenden. Ihre Komponente kann in den Kontext schauen und entweder die vorhandenen dragDropManager
im Kontext weitergeben oder einen eigenen erstellen. Es scheint jedoch etwas zerbrechlich.
Leider besteht die einzige Lösung, die mir derzeit einfällt, darin, die endgültige Komponente so zu exportieren, wie sie ist, und vom Benutzer zu erwarten, dass er einen DragDropContext mit einem Backend seiner Wahl hinzufügt. Was denken Sie?
Ich denke, das ist die flexibelste Lösung. Sie können sich dort auch eine Meinung bilden und <MyComponentContext>
exportieren, für die DragDropContext(HTML5Backend)
.
Exportieren Sie
<MyComponentContext>
, dasDragDropContext(HTML5Backend)
Es tut mir leid, ich verstehe das nicht ganz. Können Sie das etwas näher erläutern?
export default function MyTagControlContext(DecoratedClass) {
return DragDropContext(HTML5Backend)(DecoratedClass);
}
und Sie können Benutzer anweisen, entweder ihre Komponente der obersten Ebene in MyTagControlContext
zu verpacken oder DragDropContext
direkt zu verwenden, wenn sie bereits React DnD verwenden.
Ah! Wie wäre es damit? Sieht das zu hässlich aus?
// in main component file
module.exports = {
WithContext: DragDropContext(HTML5Backend)(ReactTags),
WithOutContext: ReactTags
};
Die Nutzung kann dann so etwas wie sein
var ReactTags = require('react-tags').WithContext; // if your app doesn't use react-dnd
var ReactTags = require('react-tags').WithOutContext; // if your app already uses react-dnd.
Ich glaube nicht, dass dies funktionieren würde, da jedes <ReactTags>
eine eigene Kopie des Backends erhalten und zu dem oben eingefügten unveränderlichen Fehler führen würde, da diese Backends dieselben globalen Fensterereignisse behandeln.
Was meiner Meinung nach funktionieren wird, ist, dass Sie dragDropManager
manuell erstellen können (genau wie DragDropContext
intern) und dieselbe Instanz für alle ReactTag
Instanzen verwenden können - mit einem Fallback auf die Manager definiert in context
.
Ich meine, so etwas aus Ihrer Bibliothek zu exportieren:
let defaultManager;
function getDefaultManager() {
if (!defaultManager) {
defaultManager = new DragDropManager(HTML5Backend);
}
return defaultManager;
}
class ReactTagContext {
static contextTypes = {
dragDropManager: PropTypes.object.isRequired
};
static childContextTypes = {
dragDropManager: PropTypes.object.isRequired
};
getChildContext() {
return {
dragDropManager: this.context.dragDropManager || getDefaultManager()
};
}
render() {
return <ReactTag {...props} />
}
}
Vielen Dank, Dan! Ich werde das ausprobieren und mich bei Ihnen melden. Vielen Dank, dass Sie den Code geteilt haben: grinsend:
Kein Problem. Wenn Sie dies so tun, exportieren Sie einfach diese Klasse, anstatt ReactTags
direkt zu exportieren. Es sollte "wie es ist" ohne Wrapper oder Dekorateure verwendbar sein.
Also Dan! Zum Teufel habe ich oben die Lösung für mehrere Exporte
// in main component file
module.exports = {
WithContext: DragDropContext(HTML5Backend)(ReactTags),
WithOutContext: ReactTags
};
In meiner anderen App habe ich versucht , die Komponente ohne Kontext zu und zu meiner großen Freude scheint sie gut zu funktionieren!
Denken Sie, dass dies eine hackige Lösung ist und ich sollte mit dem fortfahren, was Sie vorgeschlagen haben, oder sollte ich dies zulassen?
@ prakhar1989 Sind Sie sicher, dass dies mit mehreren <Tags />
auf der Seite funktioniert?
Du hattest mich für eine Sekunde dort! : stick_out_tongue:
Zum Glück funktioniert es!
Hmm, dann ist es vielleicht in Ordnung ;-). Lassen Sie mich wissen, wenn Sie Probleme mit diesem Ansatz haben!
Wird besorgt! Nochmals vielen Dank für all Ihre Hilfe.
PS: Haben Sie bessere Benennungsideen für WithContext
und WithoutContext
?
@ prakhar1989 Ich würde wahrscheinlich nur die Version WithContext
direkt exportieren und NoContext
als statisches Feld darauf setzen.
Ich stoße auf ein ähnliches Problem und möchte besser verstehen, warum diese Einschränkung überhaupt besteht, da das Schreiben wiederverwendbarer Komponenten dadurch ziemlich schwierig wird. So wie es ist, muss jede Komponente, die react-dnd verwendet, verschiedene Kontexte kennen, die in der Anwendung vorhanden sein können, und diese entsprechend behandeln. Es wäre vorzuziehen, wenn jede Komponente ihr eigenes Drag-Verhalten / ihren eigenen Kontext verwalten könnte, unabhängig davon, was im Rest der Anwendung sonst noch vor sich geht.
Zum Beispiel möchte ich vielleicht einen Anwendungsbildschirm mit mehreren Komponenten zum Hochladen von Dateien, einem sortierbaren Menü und einem Spiel mit ziehbaren Elementen. Jede dieser Komponenten hat sehr unterschiedliche Möglichkeiten, mit Drag-Ereignissen umzugehen, und sollte wirklich für ihren eigenen Kontext verantwortlich sein.
Meine erste Frage ist, warum dies nicht einfach im HTML5Backend-Code geschieht.
setup() {
...
// Events already setup - do nothing
if (this.constuctor.isSetUp) return;
// Don't throw an error, just return above.
//invariant(!this.constructor.isSetUp, 'Cannot have two HTML5 backends at the same time.');
this.constructor.isSetUp = true;
...
}
Warum nicht einfach im HTML5Backend-Code?
Das ist ein großartiger Punkt. Wenn die Komponente mehrere Backends erkennen kann, kann sie dann nicht direkt die Logik haben, auf das vorhandene Backend im Gültigkeitsbereich zurückzugreifen?
Hallo @gaearon, ich DragDropContext
was diesen Fehler verursacht. Ich habe versucht, dem obigen Thread zu folgen, aber mir ist nicht ganz klar, was ich tun kann, damit diese separaten Reaktionskomponenten einen Kontext gemeinsam nutzen, ohne alles andere auf meiner Seite in "Reagieren" zu konvertieren (nicht ideal). Ich bin ein bisschen mit der ES6-Syntax vertraut, arbeite aber an einem Projekt, das noch ES5 verwendet. Gibt es eine Möglichkeit, das gemeinsame Konzept von DragDropManager
von oben anzuwenden? Ich habe es bisher versucht und ich habe anscheinend keinen Zugriff auf DragDropManager
da es in dnd-core
Vielen Dank für Ihre Hilfe und für diese tolle Bibliothek!
PS Wenn es darauf ankommt, verwende ich ngReact.
@ prakhar1989 @globexdesigns @gaearon
Ich frage mich das Gleiche, warum HTML5-Backend das Backend nicht einfach wiederverwenden kann, wenn mehrere verwendet werden. Laut meinem vorherigen Kommentar macht dies React-Dnd für mich wirklich unbrauchbar, da ich mehrere Reaktionsbereiche innerhalb einer eckigen Seite habe, die in der Lage sein müssen, DnD untereinander auszuführen, und damit gegen eine Wand stoße.
Hat jemand eine schnelle Lösung dafür? Ich bin in meiner Entwicklung an einem toten Punkt angelangt.
@abobwhite So habe ich es gelöst. Es ist definitiv keine großartige Lösung, aber es scheint ab sofort zu funktionieren.
Hoffe das hilft,
Danke, @ prakhar1989 ! Aber ich verfolge nicht, wie der Mehrfachexport mit einem mit Kontext umhüllten und einem das Problem nicht löst. Mein Problem besteht darin, dass ich möglicherweise nicht mit react-dnd in eine andere Anwendung eingebettet werde, sondern nicht in der Lage bin, meinen gesamten dnd-fähigen Bereich (mit mehreren reaktions- und eckigen Komponenten / Anweisungen) in reag zu verpacken, sodass ich versucht habe, den Kontext nur um diese zu wickeln Reagiere auf Komponenten auf meiner Seite, die DnD unterstützen ... Ich würde gerne den Ansatz von @gaearon von oben ausprobieren, aber ich habe keinen Zugriff auf die DragDropManager
um eine neue zu erstellen ...
Ich habe genau das gleiche Problem. Ich stimme @abobwhite voll und ganz zu, dass dadurch Komponenten weniger wiederverwendbar werden.
Dieser Thread hat mich dazu gebracht, mein unveränderliches Problem zu lösen, indem ich die HTML5Backend
und DragDropContext
in meiner Komponentenhierarchie nach oben verschoben habe, genau wie in den Dokumenten empfohlen .
Das ist ein komisches Problem. Ich arbeite an einer verschachtelten nachbestellbaren Komponente und habe DragDropContext in der übergeordneten Komponente verschachtelt. Es scheint eigenständig zu funktionieren (aber es hat immer noch verschachtelten DragDropContext).
Wenn ich diese Komponente jedoch in einem anderen Projekt verwende, in dem DragDropContext über der Hierarchie initialisiert wurde, wird dieser Fehler angezeigt.
Ich bin auf dieses Problem mit einer Anwendung gestoßen, an der ich arbeite. Ich hatte die volle Kontrolle über alle Komponenten, also habe ich statt @DragDropContext(HTMLBackend)
etwas verwendet, das dem @gaearon- Code in diesem Kommentar sehr nahe kommt , um ein decorator
zu erstellen, das einen gemeinsamen Widerstand ergibt Kontext löschen. Es funktioniert wirklich gut.
Mir ist gerade das Gleiche passiert und das Problem war, dass ich ComponentA hatte, das @DragDropContext(HTMLBackend)
und dann ComponentB, das auch @DragDropContext(HTMLBackend)
.
ComponentB wurde in ComponentA importiert, was den Fehler für mich verursacht hat. Alles was ich tun musste war den DragDropContext aus ComponentB zu entfernen und es funktionierte.
Was ist, wenn die App 2 DrapDropContext
, diese jedoch nicht Eltern und Kind sind?
Mein Fall:
Ich kann childContext nicht überprüfen, da die zweite Komponente kein untergeordnetes Element der ersten dnd-Komponente / des ersten dnd-Kontexts ist
Um mein Problem zu lösen, habe ich einen Singleton mit diesem Code erstellt:
import { DragDropManager } from 'dnd-core';
import HTML5Backend from 'react-dnd-html5-backend';
let defaultManager;
/**
* This is singleton used to initialize only once dnd in our app.
* If you initialized dnd and then try to initialize another dnd
* context the app will break.
* Here is more info: https://github.com/gaearon/react-dnd/issues/186
*
* The solution is to call Dnd context from this singleton this way
* all dnd contexts in the app are the same.
*/
export default function getDndContext() {
if (defaultManager) return defaultManager;
defaultManager = new DragDropManager(HTML5Backend);
return defaultManager;
}
Und dann entferne ich in allen Komponenten, die ein Kind haben, das DragDropContext(HTML5Backend)
, es von diesem Kind und in ihren Eltern mache ich Folgendes:
import getDndContext from 'lib/dnd-global-context';
const ParentComponent = React.createClass({
childContextTypes: {
dragDropManager: React.PropTypes.object.isRequired,
},
getChildContext() {
return {
dragDropManager: getDndContext(),
};
},
render() {
return (<ChildComponentWithDndContext />);
},
Ich denke, der Schlüssel ist, dass ich den Kontext dnd
nur einmal initialisiere. Was denken Sie?
@andresgutgon danke. Das funktioniert auch bei mir
@andresgutgon Ihre Lösung ist großartig, aber es ist seltsam, dass DrapDropContext
DragDropManager
auf componentWillUnmount
, dh wenn Sie keine 2 DrapDropContext
s verwenden zur gleichen Zeit, sondern auf 2 verschiedenen Seiten - Sie können sie immer noch nicht verwenden. Ich werde Ihren Hack in meinem Fall versuchen, aber es ist immer noch 100% seltsam, Hacks für solch eine triviale Situation zu haben.
Auch eine Idee, warum 2 DragDropManager
etwas Schlechtes / Falsches in react-dnd
?
Ein anderer Ansatz, der etwas sauberer ist, besteht darin, ein Modul zu erstellen, das den Dekorator für ein bestimmtes Backend generiert, und dann den Dekorator bei Bedarf zu verwenden:
import {DragDropContext} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
export default DragDropContext(HTML5Backend);
import { Component } from 'react';
import withDragDropContext from '../lib/withDnDContext';
class MyComponent extends Component {
render() {
return (
<div>
// other children
</div>
);
}
export default withDragDropContext(MyComponent);
Hallo, weiß jemand, wie man löst, wenn Sie eine Komponente in DragDropContext und dann eine andere Komponente, die ebenfalls DragDropContext verwendet, eingewickelt haben, aber diese Komponente (großer Kalender reagieren) ist ein npm-Paket, also entfernen Sie es von dort gibt es keine Lösung und sie sind nebeneinander, nicht Eltern-Kind ... Sie können hier einen Blick darauf werfen https://github.com/martinnov92/TSCalendar (es ist in Arbeit - es ist also ein bisschen chaotisch: D) Danke
Ich glaube, ich habe genau das gleiche Problem mit der Verwendung des React-Mosaic- Kachel-Fenstermanagers, der React-Dnd verwendet, und meiner eigenen Komponenten, die auch React-Dnd verwenden.
Ich vermute, dass dies nicht direkt in React-Dnd gelöst wurde, aber es gibt einige Problemumgehungen, die wir anwenden können.
Gibt es ein Beispiel für einen vollständigen Arbeitscode, der dieses Problem behebt?
Die Lösung von @gcorne funktioniert
Hallo, ich habe das gleiche Problem, aber wir verwenden das React-Data-Grid und versuchen, den React-Big-Kalender hinzuzufügen
Nach dem Hinzufügen einer Komponente, die den React-Big-Kalender enthält, wird der Fehler "Nicht erfasster Fehler: Es können nicht zwei HTML5-Backends gleichzeitig vorhanden sein" angezeigt.
React-Big-Kalender Verwenden Sie React-Dnd und React-Dnd-HTML5-Backend. Wie kann dieses Problem gelöst werden?
Hallo @szopenkrk, haben Sie diese https://github.com/react-dnd/react-dnd/issues/186#issuecomment -232382782 ausprobiert?
Aber ich denke, Sie müssten eine Pull-Anfrage stellen, um auf einen großen Kalender zu reagieren und ein Dnd-Backend zu akzeptieren
Wahrscheinlich etwas zu spät, aber ich habe eine ähnliche, aber etwas andere Lösung gefunden. Ich habe eine Komponente höherer Ordnung implementiert und verwende sie einfach in allen meinen DragDropContext-fähigen Komponenten.
Code sieht folgendermaßen aus (TypeScript):
import * as React from 'react';
import {DragDropContext} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
// context singleton
let context: Function;
export function withDragDropContext<P>(
Component: React.ComponentClass<P> | React.StatelessComponent<P>,
): React.ComponentClass<P> {
// ensure a singleton instance of the context exists
if (!context) {
context = DragDropContext<P>(HTML5Backend);
}
return context(Component);
}
Und verwenden Sie es dann wie folgt in Ihren Komponenten:
import * as React from 'react';
import {withDragDropContext} from 'components/WithDragDropContext';
class MyClass extends React.Component<IMyClassProps, {}> {
// ...
}
export default withDragDropContext<IMyClassProps>(MyClass);
NB
Ich habe es noch nicht versucht, aber Sie sollten wahrscheinlich in der Lage sein, die Kontextvariable während der Deklaration zu füllen:
const context = DragDropContext(HTML5Backend);
und überspringen Sie dann den Teil if (!context) {...
.
@codeaid Danke!
Ich habe die gleiche Situation wie @andresgutgon getroffen , konnte sie aber mit seiner Methode und all der Methode, die ich hier ausprobiert
Warum hat @ guang2013 hier keine der Lösungen
Nein, immer noch keine Lösungen, ich weiß nicht, ich habe versucht, die Karte in bigCalendar zu ziehen, und ich habe die Karte als dragSource und die Kartenliste als DragAndDropContext erstellt, den Kalender als einen weiteren DragAndDropContext, dann habe ich zwei html5backend-Fehler ausgegeben eine hier bereitgestellte Methode zu verwenden, aber niemand kann mein Problem lösen. @andresgutgon , wann bist du online, kann ich direkt mit dir darüber sprechen? Sehr geschätzt.
@ guang2013 Wenn Sie eine Bibliothek verwenden, die von DragDropContext von react-dnd abhängt, funktioniert diese Technik nicht, da die Bibliothek Ihren einheitlichen dndContext nicht verwendet. In einigen Bibliotheken wie dem React-Sortable-Tree können Sie die Komponenten ohne Kontext verwenden, sodass Sie sie jedoch selbst umbrechen können.
Die Lösung von @gcorne hat für mich funktioniert, um die Verwendung von react-dnd in einer App mit react-hot-loader zu ermöglichen. Trotzdem bin ich ein wenig überrascht, dass es nicht sofort funktioniert hat!
Altes Problem, aber falls jemand anderes von Google hier landet:
Ich hatte nur 1 DND-Anbieter auf meiner Seite, ich habe keine andere Bibliothek mit DND integriert, aber ich bin trotzdem auf diesen Fehler gestoßen, etwas zufällig.
Mein Problem war, dass sich der DragDropContextProvider im BrowserRouter-Element von ReactRouter befand, wodurch das HTML5Backend bei jeder Navigation rekonstruiert werden konnte und ob sowohl die alte Seite (von der weg navigiert wurde) als auch die neue Seite (zu der navigiert wurde) DND-Elemente hatte. Der obige Fehler würde auftreten.
Die Lösung bestand darin, den DragDropContextProvider aus BrowserRouter zu entfernen.
Dieser ist für diejenigen Sterblichen gedacht, die ReactDnD zum ersten Mal ausprobiert haben, dem Tutorial gefolgt sind und ein 64-Quadrat-Schachbrett erhalten haben.
Ich konnte meinen Ritter nach Belieben herumschleppen.
Das Problem war, als ich versuchte, es in einem der BoardSquare
, warf es sich mit dem 2 HTML5-Backend-Problem auf.
Verschieben Sie, wie bereits in den Kommentaren erwähnt, das Rendering von DragDropContextProvider
außerhalb des App-Rendering-Zyklus.
Führen Sie wie in nicht direkt ein ReactDOM.render
als Rückruf für die Funktion observe
aus.
Tun Sie stattdessen Folgendes:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { DragDropContextProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import './index.css';
import App from './App';
ReactDOM.render(
<DragDropContextProvider backend={HTML5Backend}>
<App />
</DragDropContextProvider>,
document.getElementById('root')
)
App.js
import React, { Component } from 'react';
import Board from './Board';
import { observe } from './Game';
class App extends Component {
state = {
knightPosition: [0, 0]
}
componentDidMount = () => {
observe(knightPosition => {
this.setState(prevState => ({
...prevState,
knightPosition
}));
});
}
render() {
return (
<div className="App">
<Board knightPosition={this.state.knightPosition} />
</div>
);
}
}
export default App;
Ich denke, das hängt mit diesem Problem zusammen
https://github.com/prakhar1989/react-tags/issues/497
@gaearon Ich weiß, dass dies alt ist, aber wie kann ich in Ihrem Beispiel tatsächlich DragDropManager
? Es wird nirgendwo exportiert.
defaultManager = new DragDropManager(HTML5Backend);
Mein Problem ist, dass ich einige Widgets auf einer Seite über eine Drittanbieter-API rendere und DragDropContextProvider
höher als mein eigentliches Widget verschieben kann.
Dieses Problem wurde durch Löschen des alten Builds behoben.
Löschen Sie einfach den dist-Ordner oder bearbeiten Sie index.html. Ich kenne das genaue Problem nicht, aber das hat bei mir funktioniert
Glücklicherweise konnte ich die (versteckte) Antwort von @gcorne finden (https://github.com/react-dnd/react-dnd/issues/186#issuecomment-282789420). Es löste mein Problem - das als schwierig angesehen wurde - sofort.
@ prakhar1989 Ich habe das Gefühl, dass es eine echte
Die Lösung, die ich herausgefunden habe, funktioniert für mich und ermöglicht mir die Verwendung von HTML5- oder Touch-Backend:
Erstellen Sie eine Singleton-HOC-Komponente:
import {DragDropContext} from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";
import TouchBackend from "react-dnd-touch-backend";
const DragAndDropHOC = props => {
return <React.Fragment>
{props.children}
</React.Fragment>
};
export default {
HTML5: DragDropContext(HTML5Backend)(DragAndDropHOC),
Touch: DragDropContext(TouchBackend)(DragAndDropHOC),
}
Dann eine Anbieterkomponente:
const DragDrop = props => {
if (props.isTouch) {
return <DragDropContext.Touch>{props.children}</DragDropContext.Touch>
} else {
return <DragDropContext.HTML5>{props.children}</DragDropContext.HTML5>
}
};
Und benutze <DragDrop isTouch={props.isTouch} />
wo immer ich es brauche.
Für Entwickler, die auf dasselbe Problem stoßen, können Sie sich diese HOC-Lösung ansehen
Ich stoße jetzt mit Jest-Tests auf dieses Problem. HTML5-Backend wird in den Jest-Tests wie ein Singleton behandelt (weshalb das Problem auftritt ... glaube ich).
Detailliertes Problem in SO:
Haken verwenden
import { createDndContext } from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";
const manager = useRef(createDndContext(HTML5Backend));
return (
<DndProvider manager={manager.current.dragDropManager}>
....
</DndProvider>
)
Eine bessere Lösung mit Hooks (danke @jchonde):
import { DndProvider, createDndContext } from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";
import React, { useRef } from "react";
const RNDContext = createDndContext(HTML5Backend);
function useDNDProviderElement(props) {
const manager = useRef(RNDContext);
if (!props.children) return null;
return <DndProvider manager={manager.current.dragDropManager}>{props.children}</DndProvider>;
}
export default function DragAndDrop(props) {
const DNDElement = useDNDProviderElement(props);
return <React.Fragment>{DNDElement}</React.Fragment>;
}
dann können Sie also woanders verwenden:
import DragAndDrop from "../some/path/DragAndDrop";
export default function MyComp(props){
return <DragAndDrop>....<DragAndDrop/>
}
Meine Lösung:
Stellen Sie sicher, dass die untergeordnete Komponente react-dnd
direkt importiert.
Übergeben Sie die Komponenten DragDropContext
und HTML5Backend
von der übergeordneten an die untergeordnete Komponente.
Das Hinzufügen eines eindeutigen Schlüssels zum DragDropContextProvider-Tag löst das Problem <DragDropContextProvider backend={HTML5Backend} key={Math. random()}></DragDropContextProvider>
Im Typoskript habe ich die folgende Komponente erstellt. (danke @jchonde @ttessarolo )
import { DndProvider, createDndContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import React, { PropsWithChildren, useRef } from 'react';
const RNDContext = createDndContext(HTML5Backend);
function DragAndDrop({ children }: PropsWithChildren<{}>): JSX.Element {
const manager = useRef(RNDContext);
return <DndProvider manager={manager.current.dragDropManager}>{children}</DndProvider>;
}
export default DragAndDrop;
Und eine Komponente wie diese verwendet
function SomeComponent(): JSX.Element {
return (
<DragAndDrop>
...
</DragAndDrop>
);
}
Das Hinzufügen eines eindeutigen Schlüssels zum DragDropContextProvider-Tag löst das Problem
<DragDropContextProvider backend={HTML5Backend} key={Math. random()}></DragDropContextProvider>
Gut gemacht!
Hilfreichster Kommentar
Ein anderer Ansatz, der etwas sauberer ist, besteht darin, ein Modul zu erstellen, das den Dekorator für ein bestimmtes Backend generiert, und dann den Dekorator bei Bedarf zu verwenden:
lib / withDragDropContext.js
components / MyComponent.js