Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using React DnD with styled components. #1021

Closed
joetidee opened this issue May 7, 2018 · 14 comments
Closed

Using React DnD with styled components. #1021

joetidee opened this issue May 7, 2018 · 14 comments
Labels

Comments

@joetidee
Copy link

joetidee commented May 7, 2018

I need to use React DnD with styled components.

I raised this question on stackoverflow, but have also posted this issue here in the hope of obtaining an answer:
https://stackoverflow.com/questions/50220622/how-to-use-react-dnd-with-styled-component

@Rinaldo
Copy link

Rinaldo commented May 8, 2018

Edit: thanks to @zainfathoni for the suggestion to remove findDOMNode

I recently ran into this issue myself and found that Dan answered this question a while ago. I adapted his solution to Semantic UI using its Ref component.

Here's an example with Semantic UI

import React from 'react'
import { Item, Ref } from 'semantic-ui-react'
import { DragSource } from 'react-dnd'

const MyItem = props => (
    <Item>
        <Item.Content>
            <Item.Header>{props.header}<Item.Header>
            <Item.Content>{props.content}<Item.Content>
        </Item.Content>
    </Item>
)

const DraggableItem = props => {
  const { connectDragSource } = props
  return (
    <Ref innerRef={instance => connectDragSource(instance)}>
      <MyItem {...props} />
    </Ref>
  )
}

export default DragSource(...)(DraggableItem)

@zainfathoni
Copy link

zainfathoni commented May 21, 2018

You can just use Styled Component's innerRef to get the underlying DOM node, then you can call your connectDragSource to it.

Apparently you don't need ReactDOM's findDOMNode() at all in Styled Components, because the innerRef already gives you the actual underlying DOM node.

In your case, it should be like this:

class MyComponent extends Component {
...
    render() {
        const { connectDragSource } = this.props;
        return (
            <StyledComponent
                innerRef={instance => connectDragSource(instance)}
            />
        )
    }
}

You can also look at my implementation of Knight component for the official chess tutorial as a reference.
It is also accessible through CodeSandbox.

@artooras
Copy link

I have a similar use case, only inside of a styled-component I use an Icon component from react-fontawesome, like so:

const Container = styled.li`...`
const DragHandle = styled(FontAwesomeIcon).attrs({...})`...`

function Task(props) {
  return (
    <Container innerRef={instance => connectDropTarget(connectDragPreview(instance))}>
    <DragHandle innerRef={instance => connectDragSource(instance)} />
}

Using the techique suggested by @zainfathoni above works well on the Container component which is based on a native li tag. However, using it on DragHandle which is based on FontAwesomeIcon gives me the following error:

TypeError: node.setAttribute is not a function

Any ideas how I can 'dig down' to the native span tag that fontawesome renders?

@darkowic
Copy link

@artooras you probably have solved your problem until now but here is the solution - #347 (comment)

ref={instance => {
  connectDragSource(instance);
  connectDropTarget(instance);
}}

@rzkhosroshahi
Copy link

@darkowic
How can I use new Ref react API to solve this problem?

@darkowic
Copy link

@rzkhosroshahi what do you exactly mean?

@rzkhosroshahi
Copy link

@darkowic
I wanna use custom component inside React DnD, but in new ref React API you cant use ref props as a callback function, like thisref={instance => { connectDragSource(instance); connectDropTarget(instance); }}.
my question is that how do like this snippet code for new ref.

@zainfathoni
Copy link

@rzkhosroshahi
Do you mean this createRef API?

I think we can't use that API for this.
Anyway, there's no plan to remove the callback API, so you can still use the callback API for this.

Just as they noted in the createRef API docs:

Callback refs will continue to be supported in addition to the new createRef API.
You don’t need to replace callback refs in your components. They are slightly more flexible, so they will remain as an advanced feature.

@darkowic
Copy link

darkowic commented Oct 26, 2018 via email

@ViggoV
Copy link

ViggoV commented Jan 18, 2019

<StyledComp ref={instance => connectDragSource(instance)} />

works flawlessly for me, EXCEPT it seems to completely break PropTypes as described in my SO question here...

It think it must be something with the refs, since I have several other components which uses one or the other as well as a few which combines the two using native DOM element wrappers..

@rzkhosroshahi
Copy link

<StyledComp ref={instance => connectDragSource(instance)} />

works flawlessly for me, EXCEPT it seems to completely break PropTypes as described in my SO question here...

It think it must be something with the refs, since I have several other components which uses one or the other as well as a few which combines the two using native DOM element wrappers..

Is that work in production? I used this approach but when I building project my component is not dragged anymore.

@ViggoV
Copy link

ViggoV commented May 6, 2019

@rzkhosroshahi Minification seems to break it. It's not in production yet, so I haven't found a solution, but as long as i set minimize: false under optimization in my webpack config it works.

@stale
Copy link

stale bot commented Jul 6, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Jul 6, 2019
@stale stale bot closed this as completed Jul 13, 2019
@Raduuu
Copy link

Raduuu commented Nov 22, 2019

I have the same problem. My question is, does it work when we're using react-dnd with their hooks ( useDrag and useDrop) and not decorators?

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants