atlassian / react-beautiful-dnd

Beautiful and accessible drag and drop for lists with React
https://react-beautiful-dnd.netlify.app
Other
32.93k stars 2.52k forks source link

DragDropContext with Ref #1482

Open petermikitsh opened 4 years ago

petermikitsh commented 4 years ago

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).

tran-zenfolio commented 4 years ago

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

petermikitsh commented 4 years ago

@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.

alexreardon commented 4 years ago

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

BrunoWinck commented 4 years ago

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'),

Bikrant-kumar commented 3 years ago

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 .

ShaunJerry commented 3 years ago

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 .

Same situation as yours, did you solved it now?

Bikrant-kumar commented 3 years ago

Yes it is solved now, In test files you need to mention DragDropContext, Droppable and Draggable(what ever required) before the calling component for which you are writing test cases .

imakecodes commented 1 year ago

Thank you @Bikrant-kumar, this helped about how to quickly solve the issue here. To help anyone in the future, can see this README about the DragDropContext

nappalm commented 1 month ago

in short the DragDropContextmust be the first element after the return ( <DragDropContext> ....