findDOMNode()
の使用は推奨されなくなりました。 実際、それを使用する場合、Reactは使用しないように警告します。 いくつかの例では、refを使用して置き換えることができないと思われる場所でfindDOMNodeを使用しています。 findDOMNodeを使用する必要がなくなった場合は、他のものを使用するようにこれらを更新する必要があります。
この具体的な例の1つは、 https ://github.com/gaearon/react-dnd/blob/master/examples/04%20Sortable/Simple/Card.js#L34です。
const cardTarget = {
hover(props, monitor, component) {
const dragIndex = monitor.getItem().index;
const hoverIndex = props.index;
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
// Determine rectangle on screen
const hoverBoundingRect = findDOMNode(component).getBoundingClientRect();
// Get vertical middle
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
// Determine mouse position
const clientOffset = monitor.getClientOffset();
// Get pixels to the top
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
// Only perform the move when the mouse has crossed half of the items height
// When dragging downwards, only move when the cursor is below 50%
// When dragging upwards, only move when the cursor is above 50%
// Dragging downwards
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return;
}
// Dragging upwards
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return;
}
// Time to actually perform the action
props.moveCard(dragIndex, hoverIndex);
// Note: we're mutating the monitor item here!
// Generally it's better to avoid mutations,
// but it's good here for the sake of performance
// to avoid expensive index searches.
monitor.getItem().index = hoverIndex;
}
};
その他の例: https ://github.com/gaearon/react-dnd/search?l = JavaScript&q = finddomnode&utf8 =%E2%9C%93
これを解決するための推奨される方法は何ですか?
推奨される方法は、参照を使用することです。https ://facebook.github.io/react/docs/refs-and-the-dom.htmlを参照してください。
その後、 component.passedRefName.getBoundingClientRect()
を呼び出すことにより、渡された参照にアクセスできます。
私たちがそれを私たちの側で修正した方法は次のとおりです:
ドラッグ可能なもの:
<li className="draggable-card" ref={(elm) => {this.card = elm;}}>
そして、 DropTarget
hover
メソッドの内部。
hover (props, monitor, component) {
// code
const {decoratedComponentInstance} = component;
const hoverBoundingRect = decoratedComponentInstance.card.getBoundingClientRect();
// code
}
これについてもっと良い方法があるかどうかはわかりません。おそらく@gaearonがこれに光を当てることができます。 それは大歓迎です。
これは、Facebookのドキュメントから推奨される方法です。 同じようにやっています
時間があれば、後で見ていきます。 それまでの間、PRをお気軽にカットしてください
refアプローチを採用していますが、 component.decoratedComponentInstance
はnull
です。
参考までに、コンポーネントはドラッグとドロップの両方が可能です。
export default flow(
DragSource('NavItem', navItemDragSource, dragCollect),
DropTarget('NavItem', navItemDropSource, dropCollect)
)(NavigationItem);
NavigationItem
コンポーネントは、 hover
で使用する予定の参照を設定します。
class NavigationItem extends React.Component
render() {
return this.props.connectDropTarget(this.props.connectDragSource(
<section
ref={element => (this.navItemElement = element)}
</section>
}
}
そしてhover
:
const navItemDropSource = {
hover: (props, monitor, component) => {
console.log(component.decoratedComponentInstance); // prints null
}
}
ここで何が欠けているのか分かりますか?
@ndelage
私たちのアプリでは、おおよそ次のようになります。
..some code
const itemTarget = {
hover(props, monitor, component) {
if (monitor.isOver()) {
...some code
const bounds = component.node.getBoundingClientRect()
...some code
return result;
}
}
}
..some code
@DragSource(ITEM_TYPE, itemSource, collectSource)
@DropTarget(ITEM_TYPE, itemTarget, collectDrop)
class DraggableItem extends Component {
render() {
const { connectDragSource, connectDropTarget } = this.props;
return connectDragSource(
connectDropTarget(
<div
className="draggable-item"
ref={ node => (this.node = node) }
>
<Item { ...this.props } />
</div>
)
);
}
}
export default DraggableItem
あなたの例では、要素paramをthis.naItemElement
に割り当てていることがわかりますが、 hover
メソッドでは、 naItemElement
をまったく参照していません。 あなたはそれをそのようなものと呼ぶべきです:
const navItemDropSource = {
hover: (props, monitor, component) => {
console.log(component.navItemElement); // you should get the DOM node reference now
}
}
動作しています! トリックは最初にconnectDropTarget
を呼び出すことでした。 connectDragSource
がdecoratedComponentInstance
$を設定するとは思いません(何らかの理由でref変数がcomponent
に設定されていないため、 component.decoratedComponentInstance
でのみ使用できます)。
作業バージョンは次のようになります。
class NavigationItem extends React.Component
render() {
return this.props.connectDragSource(this.props.connectDropTarget(
<section
ref={node => (this.node = node)}
>
{this.props.name}
</section>
));
}
}
const navItemDropSource = {
hover: (props, monitor, component) => {
console.log(component.decoratedComponentInstance.node.getBoundingClientRect());
}
}
助けてくれてありがとう@beniutek
この機能が廃止されることを心配しているのは私だけではありません。 私は現在、 https://github.com/mozmorris/react-webcamにあるサードパーティの「Webcam」コンポーネントを使用しています。 このコンポーネントはfindDOMNodeを使用しており、refを使用して機能を置き換える方法がわかりません。 注:ここでrefが使用されていることはわかりますが、src / react-webcam.jsの(非常に短い)ソースコードを見ると、findDOMNodeも使用されています。
このコンポーネントの簡単な使用例を次に示します。
class WebcamCapture extends React.Component {
setRef = (webcam) => {
this.webcam = webcam;
}
capture = () => {
const imageSrc = this.webcam.getScreenshot();
};
render() {
return (
<div>
<Webcam
audio={false}
height={350}
ref={this.setRef}
screenshotFormat="image/jpeg"
width={350}
/>
<button onClick={this.capture}>Capture photo</button>
</div>
);
}
}
refsを使用するようにこれを変更したい場合、サンプルコードでは、このサードパーティライブラリのユーザーがビデオdom要素とgetusermediaAPIを使用しているWebカメラコンポーネントのdom構造を理解する必要があると思います。 サードパーティのコンポーネントユーザーにコンポーネントのDOM構造を理解するように要求することは、控えめに言っても理想的ではありません。 refを使用してこれを行うためのより簡単な方法が見つからない場合はお知らせください。
この問題に苦労し、 @ ndelageと@beniutekのソリューションを使おうとする人のために、 component.decoratedComponentInstance
はcomponent.getDecoratedComponentInstance()
に置き換えられました(ここに記載されています)。
必要なものは次のとおりです。
class NavigationItem extends React.Component
constructor(props){
super(props);
this.node = React.createRef();
}
render() {
const { connectDragSource, connectDropTarget } = this.props;
return connectDragSource(connectDropTarget(
<section ref={this.node}>
{this.props.name}
</section>
));
}
}
const navItemDropSource = {
hover: (props, monitor, component) => {
console.log(component.getDecoratedComponentInstance().node.getBoundingClientRect());
}
}
誰かがすぐに例を更新できるようになることを願っています。
画像上にいくつかのピンを追加し、ドロップコンポーネントのビューポート位置を取得するために、 @ QuentinRoyが提案したように参照node
を追加しましたが、 getDecoratedComponentInstance()
は機能しませんでした(関数)。
ドロップターゲット仕様のdrop
メソッドのcomponent
パラメーターでnode
参照を直接取得できることを確認しました。
drop: (props, monitor, component) => {
console.log(component.node.current.getBoundingClientRect())
}
この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。
最も参考になるコメント
動作しています! トリックは最初に
connectDropTarget
を呼び出すことでした。connectDragSource
がdecoratedComponentInstance
$を設定するとは思いません(何らかの理由でref変数がcomponent
に設定されていないため、component.decoratedComponentInstance
でのみ使用できます)。作業バージョンは次のようになります。
助けてくれてありがとう@beniutek