title: Drag and drop between two React components
body: <p>I am trying to create a React app where I can drag and drop a DOM element from a "palette" of available DOM elements into a blank "canvas" area in the second component. The available elements appear as an unordered list of React components the user can use to build a customized website. (I am basically trying to copy Wix.)</p>
  
  <p>I am just learning so I am copying heavily -- I don't really understand the limitations of HTML5 Drag N Drop. Maybe it doesn't work at all between React components.</p>
  
  <p>If I were trying to drag and drop from Component A into Component A, it would be easy -- HTML5 can do that and I've read about it. But I don't know how to adapt it to drag and drop from Component A into Component B.</p>
  
  <p>I've tried copying the <code>onDrop</code> function, "drop()", from Component A to Component B but that didn't work.</p>
  
  <p>Maybe I need a library like "react-beautiful-dnd" to accomplish this?</p>
  
  <p>Here is my code as it is:</p>
  
  <p>Component A:</p>
  
  <pre><code>import React, { Component } from "react";
  
  class Palette extends Component {
      dragStartHandler = event =&gt; {
          event.dataTransfer.setData("text/plain", event.target.id); // returns undefined ??
          console.log(event);
      };
  
      dragendHandler = event =&gt; {};
  
      dragEndHandler = event =&gt; {
          console.log("Ended drag");
      };
  
      dragStart = event =&gt; {
          event.dataTransfer.setData("text", event.target.id);
          console.log("Drag started");
      };
  
      drop = event =&gt; {
          if (event.target.id) {
              event.dataTransfer.getData("text");
              event.dataTransfer.clearData();
          }
      };
  
      render() {
          return (
              &lt;div className="palette-container"&gt;
                  &lt;h3&gt;Your Palette&lt;/h3&gt;
                  &lt;ul&gt;
                      &lt;li
                          id="header"
                          draggable="true"
                          onDrop={this.drop}
                          onDragStart={this.dragStartHandler}
                          onDragOver={event =&gt; event.preventDefault()}
                          onDragEnd={this.dragEndHandler}
                      &gt;
                          Header
                      &lt;/li&gt;
                      &lt;li&gt;Second component I wish to drop&lt;/li&gt;
  
                  &lt;/ul&gt;
              &lt;/div&gt;
          );
      }
  }
  
  export default Palette;
  </code></pre>
  
  <p>Component B looks approximately like Component A (because I don't know what else to write).</p>
  
  <p>Here is what I imagine a fully functional example would involve. Something in the palette component allows the canvas component to know when its time to create a new DOM element.</p>
  
  <p>Palette:</p>
  
  <pre><code>class Palette extends Component {
      fireCreateComponent = (elementType) =&gt; {
          createComponent(elementType);
      }
  
  render() {
          return (
              &lt;div className="palette-container"&gt;
                  &lt;h3&gt;Your Palette&lt;/h3&gt;
                  &lt;ul&gt;
                      &lt;li
                          id="header"
                          draggable="true"
                          onDragStart={this.fireCreateComponent()}
                      &gt;
                          Draggable Header
                      &lt;/li&gt;
                      &lt;li
                          id="headline"
                          draggable="true"
                          onDragStart={this.fireCreateComponent()}
                      &gt;
                          Draggable Headline
                      &lt;/li&gt;
                      &lt;li
                          id="text-area"
                          draggable="true"
                          onDragStart={this.fireCreateComponent()}
                      &gt;
                          Draggable Text Area
                      &lt;/li&gt;
                      // and so on to create different components in the Canvas section
                  &lt;/ul&gt;
              &lt;/div&gt;
          );
      }
  
  </code></pre>
  
  <p>Canvas:</p>
  
  <pre><code>class Canvas extends Component {
      createComponent = (componentType, props) =&gt; {
          React.createElement(&lt;componentType props={props}/&gt;)
  
  render() {
          return (
              &lt;div className="canvas-container"&gt;
                  &lt;h3&gt;Drag Elements Here&lt;/h3&gt;
                  &lt;div className="canvas"&gt;
                      &lt;ul&gt;
                          &lt;li&gt;Empty Space 1&lt;/li&gt;
                          &lt;div
                              onDrop={this.createComponent}
                          &gt;
                              {" "}
                          &lt;/div&gt;
                          &lt;li&gt;Empty Space 2&lt;/li&gt;
                          &lt;div
                              onDrop={this.createComponent}
                          &gt;
                              {" "}
                          &lt;/div&gt;
                      &lt;/ul&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
          );
      }
  
  </code></pre>