New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot have two HTML5 backends at the same time #186
Comments
Check out the source for DragDropContext. I think you should be able to reuse the existing manager if it is specified by a component above the tree. But it's still a tricky question.. Do you have any proposed solutions? |
Even if this is possible, the component that is exported should be able to work independently as well, and in cases where the backend exists (in the app where the component is being used) somewhere up the chain should be reused. I'll try to read the source and see if this can be pulled off. Unfortunately, the only solution I can think of right now, is to export the final component as it is, and expect the user to add a |
Yes, this is possible by not using
I think this is the most flexible solution. You can also be opinionated there and export |
I'm sorry, I don't quite understand this. Can you clarify this a bit more? |
export default function MyTagControlContext(DecoratedClass) {
return DragDropContext(HTML5Backend)(DecoratedClass);
} and you can tell users to either wrap their top-level component into |
Ah! How about this? Does this look too ugly? // in main component file
module.exports = {
WithContext: DragDropContext(HTML5Backend)(ReactTags),
WithOutContext: ReactTags
}; The usage can then be something like 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. |
I don't think this would work because each |
What I think will work is you can manually create |
I mean exporting something like this from your library: 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} />
}
} |
Thanks a lot, Dan! I'll try this out and get back to you. Thank you for sharing the code 😀 |
No prob.. If you do it like this, just export that class instead of exporting |
So Dan! For the heck of it, I was trying out the multiple exports solution above - // in main component file
module.exports = {
WithContext: DragDropContext(HTML5Backend)(ReactTags),
WithOutContext: ReactTags
}; In my other app, I tried importing the component without the context and much to my delight, it seems to be working fine! Do you think this is a hacky solution and I should go ahead with what you've proposed or should I let this be? |
@prakhar1989 Are you sure this works with multiple |
Hmm, then maybe it's fine ;-). Let me know if you have any issues with this approach! |
Will do! Thanks a ton again for all your help. PS: Do you have better naming ideas for |
@prakhar1989 I'd probably just export |
I'm running into a similar issue and I'd like to better understand why this limitation exists in the first place because it's making writing re-usable components quite difficult. As it is, each component that uses react-dnd needs to be aware of various contexts that may exist in the application and deal with them accordingly. It would be preferable if each component could manage its own drag behaviour/context regardless of what else may be going on in the rest of the application. For example, I may want to have an application screen which has several File Upload components, a sortable menu and a game with draggable elements. Each of those components have very different ways of dealing with drag events, and should really be in charge of their own context. My first question, is why not simply do this inside the HTML5Backend code?
|
This is a great point. If the component is able to detect multiple backends can't it directly have the logic of falling back to the existing backend in scope? |
Hi @gaearon - I am running into this issue as well except in my case, I have a page in which I've pieced together disparate react components within an angular template due to (angular) performance. What I have is a page which builds questions, choices, and more in a recursive tree structure. I also have a toolbar and a question library that use DnD to add things to the question tree. My problem is that I have now setup multiple react components that live within an angular context. Because of this, I am wrapping each of those with a Thanks for your help and for this awesome library! P.S. If it matters, I'm using ngReact. |
@prakhar1989 @globexdesigns @gaearon I am wondering the same thing why HTML5 backend can't just re-use the backend if multiple are used? Per my previous comment, this is really making react-dnd unusable for me as I have multiple react areas within an angular page that need to be able to DnD between each other and am hitting a wall with this. Anyone have any quick fix for this? I'm at a dead stop in my development. |
@abobwhite This is how I've solved it. It's definitely not a great solution but it seems to work as of now. Hope this helps, |
Thanks, @prakhar1989 ! But I'm not following how the multiple export with one wrapped with context and one not solves the issue. My problem is not being potentially embedded into another application with react-dnd but rather not being able to wrap my entire dnd-enabled area (with several react and angular components/directives) in react so I was trying to wrap the context around just those react components in my page that support DnD...I'd love to try @gaearon 's approach from above but I don't have access to the |
I'm having the exact same issue. I strongly agree with @abobwhite that this makes components less reusable. |
This thread led me to solving my invariant problem by moving the |
This is a weird problem. I am working on a nested reorderable component and I have DragDropContext nested inside the parent one. It seems to work standalone (but it still has nested DragDropContext). But when I use that component inside another project which has DragDropContext initialised above the hierarchy, I get this error. |
I ran into this issue with an application I'm working on. I had full control over all the components so I ended up instead of using |
Using hooks
|
A better solution using Hooks (thanks @jchonde):
so then you can use elsewhere:
|
My solution: |
DragDropContextProvider标签里加一个不重复的key就解决了 |
In the typescript, i made the below component. (thanks @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; And used a component like this function SomeComponent(): JSX.Element {
return (
<DragAndDrop>
...
</DragAndDrop>
);
} |
good job! |
I tried some of the suggestion above but get the following error: |
I tried lots of the suggestions above but for my use case none of them worked for me. I have a chrome extension which adds my widget directly into the DOM of webpages. This error occurs when the webpage uses The error can be solved by changing
I did the following:
This makes it so that react-dnd/packages/backend-html5/src/HTML5BackendImpl.ts Lines 97 to 114 in 339dd7a
Through my inspection, this @martinnov92 I think this approach solves the problem you mention where two codebases are both using
Likewise to @mauron85 and @szopenkrk |
using a combination of @milban and @MJGang's solution worked for me. the drag and drop singleton needed the random key generation Related to: frontend-collective/react-sortable-tree#788 |
I tried everything from above comment but typescript throwing below error: |
|
This approach worked for me. |
What is the modern approach to this? Seems both createDndContext and DragDropContext are removed |
The newer way is to use the react context API:
|
P.S. Make sure by the time you call |
@darthtrevino Can you expand on this a little more? This seems like the solution to an error I'm having but it would help if I understood it more. Thank you. |
work for me, react-dnd@16.0.1 |
it worked for me, thank you |
That works for me! Really save my ass!! react-dnd@14.0.3 |
Hi Dan,
Just a quick one - I'm trying to use my own component that has
react-dnd
as a dependency in another app which itself usesreact-dnd
so the error above expected. In this case, what would be the best way to fix this?Since the other component is my own, I can remove the
DragDropContext
call from while exporting the component but then that sacrifices the re-usability of the component. What do you advise?The text was updated successfully, but these errors were encountered: