react-grid-layout / react-draggable

React draggable component
MIT License
9.01k stars 1.02k forks source link

React component is not work in Draggable,even though provide props. #265

Open GoDotDotDot opened 7 years ago

GoDotDotDot commented 7 years ago

When I put my React component in Draggable,the terminal give me some error info:

react-with-addons.min.js:14 Uncaught TypeError: Cannot read property 'button' of undefined
    at DraggableCore._this.handleDragStart (drag.js:1068)
    at DraggableCore._this.onMouseDown (drag.js:1214)
    at Panel.onMouseDown (app.processed.js:8171)
    at Object.r (react-with-addons.min.js:14)
    at a (react-with-addons.min.js:12)
    at Object.s [as executeDispatchesInOrder] (react-with-addons.min.js:12)
    at p (react-with-addons.min.js:12)
    at f (react-with-addons.min.js:12)
    at Array.forEach (<anonymous>)
    at r (react-with-addons.min.js:16)

code

app.js

<Draggable handle=".md-panel--control" >
          <Panel className="flag"/>  
        </Draggable>

panel.js

 <div
        className={`md-panel ${className}`}
        onMouseDown={this.onMouseDown}
        onMouseUp={this.onMouseUp}
        onTouchStart={this.onTouchStart}
        onTouchEnd={this.onTouchEnd}
        style={style}
      >
        <div className='md-panel--control'>control area</div>
        <div className='md-panel--body'>body</div>
      </div>

code pen

Could you help me resolve this?thanks.

joshtronic commented 6 years ago

Try wrapping <Panel /> in a <div /> inside of <Draggable />.

Ran into something similar and wrapping my custom component in a standard one did the trick!

shmup commented 5 years ago

What @joshtronic suggested indeed worked for me. I had to provide a wrapping <div> you see here:

{React.Children.map(this.props.children, child => {
  return (
    <Draggable>
      <div>{React.cloneElement(child)}</div>
    </Draggable>
  );
})}

The children I'm mapping over here is a custom component: <Card />

It's unclear to me why this works, and I suppose it is worth documenting if it's a thing, heh

Oh, huh, I landed on this thread from a search but should note that I didn't get the error the OP mentioned. I had no error at all, and instead just wasn't able to drag the <Card /> around.

CMCDragonkai commented 5 years ago

I hit this problem as well. In fact I already had a React component that was already a div (a styled component div), and I had to wrap it in another just <div></div> before it started dragging!

AndyFong commented 4 years ago

I also encounter this problem.
Wrap the children with a div element works in most case, but finally I choose to use React Context api to solve this problem, it should be more flexible, for you can consume the injected draggable props anywhere you want in the hierarchy children components and not need to add extra div element.

Here are the sample typescript codes:

type DraggableChildrenProps = {
  style?: React.CSSProperties
  // other mouse or touch event from DraggableCore
}

const DraggableProxyContext = React.createContext<DraggableChildrenProps>(null)

const DraggableProxy: React.FC<DraggableChildrenProps> = (
  props
) => {
  const { children, ...rest } = props
  return (
    <DraggableProxyContext.Provider value={rest}>
      {children}
    </DraggableProxyContext.Provider>
  )
}

const MyDraggableComponent: React.FC = (props) => {
  return (
    <DraggableCore>
      <DraggableProxy>{props.children}</DraggableProxy>
    </DraggableCore>
  )
}

const Box: React.FC = (props) => {
  const { style: draggableStyle, ...rest } = useContext(DraggableProxyContext)
  return <div style={draggableStyle} {...rest}>{props.children}</div>
}