私は完全には理解していませんが、どうやら findDOMNode() の使用は推奨されていません。
ドラッグアンドドロップコンポーネントを作成しようとしていますが、コンポーネント変数からrefにアクセスする方法がわかりません。これは私が現在持っているものの例です:
const cardTarget = {
hover(props, monitor, component) {
...
// Determine rectangle on screen
const hoverBoundingRect = findDOMNode(component).getBoundingClientRect();
...
}
}
編集
this example では機能しないが this one では機能しないため、コンポーネントがドラッグアンドドロップのソースとターゲットの両方であることが原因である可能性があります。
Es6クラスの構文とReact(執筆時点では15)の最新バージョンを使用していると仮定すると、共有したリンクにDanの例のようにコールバック参照を添付できます。 the docs から:
HTML要素でref属性が使用されている場合、refコールバックは、基になるDOM要素を引数として受け取ります。たとえば、次のコードはrefコールバックを使用して、DOMノードへの参照を格納します。
_<h3
className="widget"
onMouseOver={ this.handleHover.bind( this ) }
ref={node => this.node = node}
>
_
次に、以前の友人findDOMNode()
またはgetDOMNode()
と同じようにノードにアクセスできます。
_handleHover() {
const rect = this.node.getBoundingClientRect(); // Your DOM node
this.setState({ rect });
}
_
動作中: https://jsfiddle.net/ftub8ro6/
React DNDは舞台裏で少し魔法をかけるので、装飾されたコンポーネントを取得するためにAPIを使用する必要があります。それらは getDecoratedComponentInstance()
を提供します基礎となるコンポーネントを取得できます。これを使用すると、期待どおりに_component.node
_を取得できます。
_hover(props, monitor, component) {
const dragIndex = monitor.getItem().index;
const hoverIndex = props.index;
const rawComponent = component.getDecoratedComponentInstance();
console.log( rawComponent.node.getBoundingClientRect() );
...
_
ここでそれは動作しています:
より良い解決策は、ドラッグ可能なコンポーネントをdiv
でラップし、それに参照を定義して、それをドラッグ可能なコンポーネントに渡すことです。
_<div key={key} ref={node => { this.node = node; }}>
<MyComponent
node={this.node}
/>
</div>
_
MyComponent
はDragSource
でラップされています。今すぐ使用できます
_hover(props, monitor, component) {
...
props.node && props.node.getBoundingClientRect();
...
}
_
(_props.node &&
_は、未定義のオブジェクトでgetBoundingClientRect
を呼び出さないようにするために追加されただけです)
findDOMNode
の代替ラッピングdiv
を追加したくない場合は、次のようにします。 @imjaredと ここで提案する解決策 の応答は機能しません(少なくとも_[email protected]
_および_[email protected]
_では)。
findDOMNode
を使用しないfindDOMNode(component).getBoundingClientRect();
の唯一の有効な代替方法は次のとおりです。
_hover(props, monitor, component) {
...
component.decoratedComponentInstance._reactInternalInstance._renderedComponent._hostNode.getBoundingClientRect();
...
}
_
これはあまり美しくなく、危険ですreact
は将来のバージョンでこの内部パスを変更する可能性があるためです!
正確な値は得られませんが、小さなdragSourceがある場合は、おそらく十分なmonitor.getDifferenceFromInitialOffset();
を使用してください。その後、戻り値は、dragSourceのサイズに応じて小さなエラーマージンでかなり予測可能です。
React-DnD
のAPIは非常に柔軟です。これを(ab)使用できます。
たとえば、React-DnDでは、基になるコンポーネントに渡されるコネクタを特定できます。つまり、それらをラップすることもできます。 :)
たとえば、ターゲットコネクタをオーバーライドして、ノードをモニターに保存します。 Symbol
を使用して、この小さなハックを外部に漏らさないようにします。
const NODE = Symbol('Node')
function targetCollector(connect, monitor) {
const connectDropTarget = connect.dropTarget()
return {
// Consumer does not have to know what we're doing ;)
connectDropTarget: node => {
monitor[NODE] = node
connectDropTarget(node)
}
}
}
hover
メソッドで、次を使用できます
const node = monitor[NODE]
const hoverBoundingRect = node.getBoundingClientRect()
このアプローチは、React-DnDのフローに便乗し、Symbol
を使用して外部の世界を保護します。
このアプローチを使用する場合でも、クラスベースのthis.node = node
refアプローチを使用する場合でも、基になるReactノードを使用します。コンシューマがReact-DnDで既に必要とされているもの以外のref
を手動で使用することを忘れないでください。また、コンシューマーもクラスコンポーネントである必要はありません。