React-beautiful-dnd: DragDropContext with Ref

Created on 10 Sep 2019  ·  5Comments  ·  Source: atlassian/react-beautiful-dnd

Expected behavior

I have a fairly distributed application architecture, where portion of the application is rendered inside of a div with a ref.

The "outer application" is represented below as the App component; the inner portion (rendered inside the ref) is the InnerApp.

The entire app is wrapped in on DragDropContext. I have a Droppable containing a number of Draggables within App, that I'd like to be able to drag from App to InnerApp.

class App extends Component {
  constructor(props) {
    super(props);
    this.innerApp = React.createRef();
  }

  componentDidMount() {
    ReactDOM.render(<InnerApp />, this.innerApp.current);
  }

  render() {
    return (
      <DragDropContext onDragEnd={this.onDragEnd}>
        <div ref={this.innerApp} />
      </DragDropContext>
    );
  }
}

class InnerApp extends React.Component {
  render() {
    return (
      <Droppable droppableId="droppable">...</Droppable>
    )
  }
}

With this structure, (to my understanding, please correct if wrong) the context can't be passed through from App to InnerApp. This leads to a runtime exception: Could not find "store" in the context of "Connect(Droppable)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(Droppable) in connect options.

Actual behavior

In it's current form-- this is expected. Here's where I get feature request-y:

I'd like to be able to inject the correct context within InnerApp. Here's some pseudocode:

import { DragDropContext } from 'react-beautiful-dnd';

class InnerApp extends React.Component {
  static contextType = DragDropContext; // something like this?
  render() {
    return (
      <Droppable droppableId="droppable">...</Droppable>
    )
  }
}

Steps to reproduce

  1. Open demo
  2. View browser console

Suggested solution?

Some way to pass context through refs.

What version of React are you using?

16.9.0

What version of react-beautiful-dnd are you running?

11.0.5

What browser are you using?

Chrome, Mac OS, latest

Demo

https://codesandbox.io/s/vertical-list-3cf46?fontsize=14

(It shows an exception being thrown. That's intentional).

idea 🤔 investigating 🕵️‍♂️

Most helpful comment

Right now it is required that a DragDropContext be at a higher level in your tree than any of the Droppables. It needs to be a shared parent

All 5 comments

I have the same issue when apply to my application with the same structure. Please help me with some ideas.

@tran-zenfolio When ejecting in and out of React's component tree, through ref's and native DOM elements, React context can't carry through. The project assumes all of the react-beautiful-dnd components are in one, complete React component tree.

Right now it is required that a DragDropContext be at a higher level in your tree than any of the Droppables. It needs to be a shared parent

I ended up with this problem as well after I refactored my app in several packages.
DragDropContext and Droppable ended up being called in two different packages.

My solution:
react-beautiful-dnd must be included only once in the app.
if DragDropContext, the context provider, is inserted in a component in another package, I export it again from the package where Droppable and Draggable are used.
A context is a shared global, true for every context provider.

an alternative solution (tested) is to share the module using webpack.
add a resolve/alias entry
'react-beautiful-dnd': path.resolve('./node_modules/react-beautiful-dnd'),

I don't have any issue like this in my react component and the app is running fine but when i am writing unit test cases for react component having redux state, while running those test cases the same issue is generated can you help me with some ideas .

Was this page helpful?
0 / 5 - 0 ratings