I don't fully understand it but apparently it isn't recommended to use findDOMNode().
I'm trying to create drag and drop component but I'm not sure how I should access refs from the component variable. This is an example of what I currently have:
const cardTarget = {
hover(props, monitor, component) {
...
// Determine rectangle on screen
const hoverBoundingRect = findDOMNode(component).getBoundingClientRect();
...
}
}
Source
Edit
It might be caused by my component being both the drag and drop source and target as I can get it to work in this example but not this one.
Summing up. React findDOMNode method is already deprecated in StrictMode. It's important to get rid of all its usages in our code to be ready to migrate to future React versions. The simplest solution is to replace it with a ref attached to the element we are interested in referencing (or a wrapper of it).
findDOMNode is an escape hatch used to access the underlying DOM node. In most cases, use of this escape hatch is discouraged because it pierces the component abstraction. It has been deprecated in StrictMode .
Assuming you're using es6 class syntax and the most recent version of React (15, at time of writing), you can attach a callback ref like Dan did in his example on the link you shared. From the docs:
When the ref attribute is used on an HTML element, the ref callback receives the underlying DOM element as its argument. For example, this code uses the ref callback to store a reference to a DOM node:
<h3
className="widget"
onMouseOver={ this.handleHover.bind( this ) }
ref={node => this.node = node}
>
Then you can access the node just like we used to do with our old friends findDOMNode()
or getDOMNode()
:
handleHover() {
const rect = this.node.getBoundingClientRect(); // Your DOM node
this.setState({ rect });
}
In action: https://jsfiddle.net/ftub8ro6/
Because React DND does a bit of magic behind the scenes, we have to use their API to get at the decorated component. They provide getDecoratedComponentInstance()
so you can get at the underlying component. Once you use that, you can get the component.node
as expected:
hover(props, monitor, component) {
const dragIndex = monitor.getItem().index;
const hoverIndex = props.index;
const rawComponent = component.getDecoratedComponentInstance();
console.log( rawComponent.node.getBoundingClientRect() );
...
Here it is in action:
https://jsfiddle.net/h4w4btz9/2/
A better solution is to just wrap your draggable component with a div
, define a ref on that and pass it to the draggable component, i.e.
<div key={key} ref={node => { this.node = node; }}>
<MyComponent
node={this.node}
/>
</div>
and MyComponent
is wrapped in DragSource
. Now you can just use
hover(props, monitor, component) {
...
props.node && props.node.getBoundingClientRect();
...
}
(props.node &&
is just added to avoid to call getBoundingClientRect
on an undefined object)
findDOMNode
If you don't want to add a wrapping div
, you could do the following.
The reply of @imjared and the suggested solution here don't work (at least in [email protected]
and [email protected]
).
The only working alternative for findDOMNode(component).getBoundingClientRect();
which does not use findDOMNode
is:
hover(props, monitor, component) {
...
component.decoratedComponentInstance._reactInternalInstance._renderedComponent._hostNode.getBoundingClientRect();
...
}
which is not very beautiful and dangerous because react
could change this internal path in future versions!
Use monitor.getDifferenceFromInitialOffset();
which will not give you precise values, but is perhaps good enough in case you have a small dragSource. Then the returned value is pretty predictable with a small error margin depending on the size of your dragSource.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With