react-sortable-tree icon indicating copy to clipboard operation
react-sortable-tree copied to clipboard

Cannot have two HTML5 backends at the same time. Conflict with react-dnd

Open alexfrize opened this issue 6 years ago • 25 comments

I use react-sortable-tree for my app which supports multiple color themes. I render each tree element with customized 'generateNodeProps'.

When I change color theme it re-renders the tree.

And everything works perfect without react-dnd. But I have another component which uses react-dnd, so I have to wrap my app to DragDropContextProvider.

<DragDropContextProvider backend={HTML5Backend}>
 ...
</DragDropContextProvider>

and import tree without dnd context. import { SortableTreeWithoutDndContext as SortableTree } from 'react-sortable-tree'; But I still have an error:

HTML5Backend.js:398 Uncaught Error: Cannot have two HTML5 backends at the same time. at HTML5Backend.setup (HTML5Backend.js:398) at DragDropManagerImpl.handleRefCountChange

The above error occurred in the <DropTarget(TreeNode)> component: in DropTarget(TreeNode) (created by Grid) in div (created by Grid) in div (created by Grid) in Grid (created by List) in List in Scrolling(List) (created by AutoSizer) in div (created by AutoSizer) in AutoSizer (created by ReactSortableTree) in div (created by ReactSortableTree) in ReactSortableTree (created by Context.Consumer) in SortableTreeWithoutDndContext (at TreeWithFilters.tsx:618)

App throws error only when I try to expand a tree node (if tree has more than 1 level). For 1 level trees there is no expand buttons and also no errors.

If I disable DragDropContextProvider and import SortableTree with dnd context import SortableTree from 'react-sortable-tree'; i don't have this error.

I tried to create a codesandbox, but couldn't reproduce it online in simplified version. Sorry about it.

But maybe some of you had similar problem and you have any ideas, how to solve it.

"react-dnd": "^7.6.0", "react-dnd-html5-backend": "^7.6.0", "react-sortable-tree": "^2.6.2",

alexfrize avatar Jul 12 '19 23:07 alexfrize

At least any ideas?

alexfrize avatar Jul 15 '19 18:07 alexfrize

The same happened to me when I was wrapping my Main class (basically the whole app) with DragDropContextProvider. The solution in my case was two wrap each Page (or Component as appropriate) within DragDropContextProvider independently.

keymandll avatar Jul 20 '19 08:07 keymandll

Thank you for this idea. But unfortunately it didn't help. If I wrap each component, that uses dnd, the app throws same error every time it tries to render wrapped component.

alexfrize avatar Jul 22 '19 19:07 alexfrize

Not reading back I may have not described my scenario accurately. The problem was basically that I had a component (let's call it "root component") that had a drag and drop context. Then, one of the children of the root component also had a drag and drop context set. This is what cause the problem in my case. Anyway, sorry it did not help.

keymandll avatar Jul 22 '19 19:07 keymandll

Anyway, thanks for trying to help.

alexfrize avatar Jul 22 '19 19:07 alexfrize

@alexfrize so basically you are saying that even though you tried to import the react-sortable-tree without the react-dnd it still tries to import the library and causing an issue on your app... am I on the right track?

lifejuggler avatar Jul 23 '19 13:07 lifejuggler

@lifejuggler, I can't say for sure.

If I use only react-sortable-tree, there is no error at all. Error appears only when I add another component, wrapped in DragDropContextProvider. And it is still working fine, but throws an error only when I change color theme and try to expand the tree. For the non-expandable tree (tree with 1 level only) there is no error at all (I think this is because it is not using dnd). All dnd functions are turned off for react-sortable-tree and, as I already mentioned, I import SortableTree without dndContext.

alexfrize avatar Jul 24 '19 16:07 alexfrize

I was seeing the same thing in our application -- had wrapped the whole app in a DragDropContextProvider at the top-level and was using SortableTreeWithoutDndContext, but got the dreaded "Cannot have two HTML5 backends at the same time" error whenever I expanded a folder node or dragged a node around.

What seemed to fix this, for me, was modifying my context wrapper to look more like what I saw in react-sortable-tree's source code.

Before, I had something like this:

import { DragDropContextProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';

const WrappedMyApp = () => {
  return (
    <DragDropContextProvider backend={HTML5Backend}>
      <MyApp />
    </DragDropContextProvider>
  );
};

But I changed it to look more like this...

import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';

const WrappedMyApp = DragDropContext(HTML5Backend)(MyApp);

...and as far as I can tell, that seemed to work okay. Couldn't really explain why, though.

menewman avatar Nov 01 '19 22:11 menewman

I was seeing the same thing in our application -- had wrapped the whole app in a DragDropContextProvider at the top-level and was using SortableTreeWithoutDndContext, but got the dreaded "Cannot have two HTML5 backends at the same time" error whenever I expanded a folder node or dragged a node around.

What seemed to fix this, for me, was modifying my context wrapper to look more like what I saw in react-sortable-tree's source code.

Before, I had something like this:

import { DragDropContextProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';

const WrappedMyApp = () => {
  return (
    <DragDropContextProvider backend={HTML5Backend}>
      <MyApp />
    </DragDropContextProvider>
  );
};

But I changed it to look more like this...

import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';

const WrappedMyApp = DragDropContext(HTML5Backend)(MyApp);

...and as far as I can tell, that seemed to work okay. Couldn't really explain why, though.

I'm trying to use this way but DragDropContext was removed since react-dnd version 9,i'dont how to solve this

harekuer avatar Jan 09 '20 03:01 harekuer

This is pretty annoying and happens with each hot reload

gusano avatar Jun 04 '20 09:06 gusano

This is pretty annoying and happens with each hot reload

Yep, this is an issue that happens always after hot reload.

dnizetic avatar Jun 10 '20 20:06 dnizetic

Any fix on this yet. Or a workaround ?

HavermansStef avatar Nov 20 '20 10:11 HavermansStef

Any fix on this yet. Or a workaround ?

@HavermansStef

My workaround was - place the DnDContext outside of BrowserRouter.

dnizetic avatar Nov 20 '20 15:11 dnizetic

Any fix on this yet. Or a workaround ?

@HavermansStef

My workaround was - place the DnDContext outside of BrowserRouter.

And the DnDContext is this:

import React, { useRef } from "react";
import PropTypes from "prop-types";
import { createDndContext, DndProvider } from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";

/**
 * This DND context is used to resolve errors: "Error: Cannot have two HTML5 backends at the same time."
 * Idea is to put the DND context OUTSIDE BrowserRouter. See comment here:
 * https://github.com/react-dnd/react-dnd/issues/186#issuecomment-453990887
 * https://github.com/react-dnd/react-dnd/issues/186#issuecomment-561631584
 */
const DnDContext = createDndContext(HTML5Backend);

export function GlobalDndContext(props) {
    const manager = useRef(DnDContext);
    return <DndProvider manager={manager.current.dragDropManager}>{props.children}</DndProvider>;
}

GlobalDndContext.propTypes = { children: PropTypes.node };

export default GlobalDndContext;

dnizetic avatar Nov 20 '20 15:11 dnizetic

Same issue here, the fix from @dnizetic and others from the internet did not work. Any other hints? The package is really great but this bug is killing me. Thanks.

jo47011 avatar Jan 14 '21 13:01 jo47011

Same issue here, the fix from @dnizetic and others from the internet did not work. Any other hints? The package is really great but this bug is killing me. Thanks.

My fix did work for us, when I placed the DnD context outside BrowserRouter we stopped getting this error.

dnizetic avatar Jan 14 '21 13:01 dnizetic

Hi @dnizetic thanks for the quick feedback.

I'm quite new to react so I'm not sure how to place anything outside the BrowserRouter. Could you please provide any further details.

Actually I'm using the react-sortable-tree as a plotly dash component as described here: https://dash.plotly.com/plugins It works fine so far except for the mentioned bug which just popped up yesterday and I have no clue why.

jo47011 avatar Jan 14 '21 19:01 jo47011

Had a similar problem switching in view between two components that had the dnd. Solved it by moving the Dnd Provider to the parent component and wrapping both components that needed it.

AlanFnz avatar Apr 23 '21 18:04 AlanFnz

@AlanFnz Can you please showcase your code? I've tried literally everything to fix this issue with react-sortable-tree and switching between two components within view but nothing works

PCPbiscuit avatar Jun 10 '21 16:06 PCPbiscuit

Wow. Actually managed to fix this myself. Wrapping my layout with dndprovider and importing SortableTreeWithoutDndContext instead of standard SortableTree seemed to work, even tho it was my initial fix attempt

PCPbiscuit avatar Jun 10 '21 17:06 PCPbiscuit

@PCPbiscuit Glad to know that you nailed it. Let me know if you need to see my fix.

afernandezminutentag avatar Jun 10 '21 17:06 afernandezminutentag

@afernandezminutentag Can you please post the fix you came upon ?

bibin-qub avatar Aug 05 '21 04:08 bibin-qub

For personal testing, you need to upgrade react-dnd and react-dnd-html5-backend to the latest version, and note that they need to be placed in peerDenepdencies.

It did solve the problem.

rpqp avatar Mar 02 '22 03:03 rpqp

The same thing has happened to me, I have tried everything that has been said on this channel, but I have not been able to obtain good results, I have chosen to clone the repository https://github.com/frontend-collective/react-sortable-tree to analyze its source code, and I have reached a perfect solution, which does not give any kind of problem

Step to perform the integration well

  1. Place the DndProvider in the top Tree of the app, as shown in the configuration of the doc
  2. When you want to call the SortableTree component you must wrap it with the Consumer property of the DndCotext
  3. Pass as dragDropManager property of the SortableTree component the value of dragDropManager of the DndContext
  4. Done, you can use this code in any part of your application without having the annoying problem Cannot have two HTML5 backends at the same time
<DndContext.Consumer>
        {({ dragDropManager }) =>
          <SortableTree
              dragDropManager={dragDropManager}
              ...
            />
        }
</DndContext.Consumer>

The versions I'm using:

  • react-dnd: "^11.1.3"
  • react-dnd-html5-backend: "^11.1.3"
  • react-sortable-tree: "^2.8.0"

DmaKill avatar Jul 25 '22 00:07 DmaKill

I don't know if anyone else will have the same problem, but removing <StrictMode> from the root component solved the error.

Cesaario avatar Jan 19 '23 13:01 Cesaario