React-dnd: 「ドロップ後にホバーを呼び出せない」をデバッグする方法は?

作成日 2016年04月19日  ·  24コメント  ·  ソース: react-dnd/react-dnd

こんにちは、
私の同僚の1人は、どういうわけかモニターの状態を壊すことができ、マウスが上がっていてもホバリングしていると考えて、次のように表示します。

screenshot 2016-04-19 16 34 56

どこからデバッグを開始するかについてのアイデアはありますか? 私はそれを再現することができず、彼はそれを週に一度見ます。
タッチバックエンドスイッチを使用して、マウスイベントもいくつか調整して処理しています。

triage wontfix

最も参考になるコメント

私もこの問題を抱えています-私の状況では、Reactコンポーネントがドロップターゲットとドラッグソースの両方です。 2つのコンポーネントがある場合、上記のエラーがスローされる前に1回ドラッグアンドドロップできます。 私が3つ持っているとき、それはエラーなしで動作します。 私はそれが単一のコンポーネント上の複数のコンテキストと関係があると思いますか?

全てのコメント24件

そこで、JSの問題を調査したところ、このエラーの前に、ドロップが発生するはずのときにユーザー定義のコールバックからエラーがスローされ、モニター/ストアの状態が壊れている可能性があることがわかりました。

私もこの問題を抱えています-私の状況では、Reactコンポーネントがドロップターゲットとドラッグソースの両方です。 2つのコンポーネントがある場合、上記のエラーがスローされる前に1回ドラッグアンドドロップできます。 私が3つ持っているとき、それはエラーなしで動作します。 私はそれが単一のコンポーネント上の複数のコンテキストと関係があると思いますか?

この問題が発生し、昨夜、特定のユースケースの回避策を見つけました。

コンテキストとして、DragSourceのリストをレンダリングしていましたが、それらのいずれかがDropTargetにドロップされた場合、それらはDragSourceのリストから削除され、DropTargetはDragSourceのコンテンツをレンダリングするコンポーネントに置き換えられます。

このドラッグアンドドロップ機能(「カテゴリ」をアイテムに一致させるコンポーネント)の重要な部分は、アイテムをドラッグソースリストに追加する機能でした。これにより、配置されたアイテムがドラッグソースに置き換えられ、ドラッグソースに追加されます。リスト。

image

現在、この例外は、すべてのカテゴリにアイテムを配置して少なくとも1つを削除した場合にのみ発生しました(リストがいっぱいでなく、1つを削除して、再度追加した場合ではありません)。 そのため、DragSourcesリストにこれが発生するための子をゼロにすることはできないという結論に達しました(おそらくコンテナ要素が消えたためですが、これをテストするのに十分な時間がありませんでした)。 これを軽減するために、配置時にDragSourcesリストからアイテムを削除する代わりに、スタイルをdisplay: none

説明するのは難しいですが、これがお役に立てば幸いです。

@PendragonDevelopmentと同じ効果があります。 私のリストは1つのアイテムから始まり、2つ目のアイテムが追加されてから、再配置できます。 Javascriptエラーが表示される前に、2つのアイテムを一度だけ並べ替えることができ、再度並べ替えることはできません。

私もこの問題を抱えています
理由はわかりませんが、最初に再配置した後、これらのエラーが表示されます

ここでも同じエラーが発生しました。

デモの例と私の例を比較したところ、コンポーネントをループするときに配列キーを使用してコンポーネントのキーインデックスの両方を設定し、デモではインデックスSortable / Simple / Container.jsのみを設定し、キーが修正されていることがわかりました。

やった、働いた!

配列の並べ替え後にコンポーネントへの参照が失われるため、キーは固定値である必要があります。

DnDを動的にコンポーネントで作成してアタッチする場合は、ライブラリを使用する必要があります。そうしないと、各コンポーネントに一意のキーを生成するためにDate.now()がそれを実行します。

{this.state.rows.map(function(row, key) {
  return (<RowComponent key={row.id} index={key} id={row.id} moveRow={that.moveRow} />);
})}

row.idはコンポーネントごとに一意です

なぜ機能するのかわかりませんが、 node-uuid's v4によって生成されたランダムキーの代わりにmodel.idを使用すると修正されました。 少なくとも、もうエラーは発生していません。

キーを修正しても問題は解決しませんでした。
これは私のコードでした

           <ContentPatch>
             {tasks.loading 
              ? <div>...loading </div>
              : this.state.containers.map((item, i) => {
                  return (
                    <TaskStage
                      key={item.id}
                      item={item}
                      tasklist={tasks.tasks}
                      onDropped={this.handleDropped}
                      onBeginningDrag={this.onBeginningDrag}
                    />
                  );
                })}
          </ContentPatch>

ドロップされたアクションごとに、すべてのアイテムをマッピングしていましたが、同じエラーが発生していました。
そして私は私の状態をに変えました

...
{tasks.loading && tasks.tasks.length===0
 ? <div>...loading </div>
...

そしてそれは解決されました。 繰り返しになりますが、マウントがこのエラーの原因だと思います。

私はこれと同じエラーに遭遇しました。

私のユースケースは次のとおりです。

  • 同じDragSourceDragTargetコンポーネント
  • ドロップで、私はルートにナビゲートしたかった

endDragDragSourceメソッド)はdropDropTargetメソッド)の後に発生することがわかりましdrop内のルートナビゲーションを処理していました。

そのロジックをendDragして、修正しました。 リファクタリングでは、ドロップがmonitor.didDrop()で完了したかどうかを確認しましたが、それほど悪くはありませんでした。

私もこの問題を抱えています。 私の場合、コンポーネントはドロップターゲットとドラッグソースの両方です。 endDragメソッドを使用して、パッチを適用したバックエンド(https://gist.github.com/nickpresta/eb5cce69d650db4c2795)を使用しようとしました。 この問題は解決しませんでした。

私のコンポーネント:

@DropTarget<HeadColOwnProps>(TaskDndTypes.headCol, headColTargetSpec, headColTargetCollector)
@DragSource<HeadColOwnProps>(TaskDndTypes.headCol, headColSourceSpec, headColSourceCollector)
class HeadColComponent extends React.Component<any, void> {
    render() {
        const props = this.props;
        return this.props.dndConnectDropTarget(
            this.props.dndConnectDragPreview(
                <div>
                    <div className={block('panels-task__drag')({start: props.dndIsDragging})}>
                        <SortingIcon
                            label={props.label}
                            arrowIsVisible={props.sortingIsPossible}
                            direction={props.sortingDirection}
                            clickHandler={props.sortingHandler}
                        />
                        {this.props.dndConnectDragSource(
                            <span className="panels-task__drag-control">
                                <SVGIcon width={10} height={10} url={'#icon-drag-and-drop-cell'} />
                            </span>
                        )}
                    </div>
                </div>
            )
        );
    }
}

使用例:

const renderHeadCellId = (): JSX.Element => {
        return (
            <TaskCellHead key="key-head-col-id" modifications={{ number: true }}>
                <HeadColComponent
                    label="#"
                    key="key-dnd-head-col-id"
                    taskColType={TaskCols.id}
                    sortingIsPossible={false}
                    taskColsOrder={taskStore.orderCols}
                    updateDragProcess={(dp: TaskColDragProcess | null) => taskStore.updateDragProcess(dp)}
                    updateOrderCols={(order: TaskCols[]) => taskStore.updateOrderCols(order)}
                    dragProcess={taskStore.dragProcess}
                />
            </TaskCellHead>
        );
    };

デコレータ設定:

const headColSourceSpec: DragSourceSpec<HeadColOwnProps> = {
    beginDrag(props: HeadColOwnProps): DraggedItem {
        return { sourceColType: props.taskColType };
    },
    canDrag(props: HeadColOwnProps): boolean {
        return props.taskColsOrder.length > 1;
    },
    endDrag(props: HeadColOwnProps, monitor: DragSourceMonitor): void {
        console.debug('endDrag');
        if (!monitor.didDrop()) {
            return;
        }
        console.debug('endDrag finish');
        props.updateOrderCols((monitor.getDropResult() as DroppedResult).newOrderCols);
    }
};

const headColTargetSpec: DropTargetSpec<HeadColOwnProps> = {
    drop(props: HeadColOwnProps, monitor: DropTargetMonitor): DroppedResult {
        console.debug('drop');
        return {
            newOrderCols: getNewOrder((monitor.getItem() as DraggedItem).sourceColType, props.taskColsOrder, props.dragProcess)
        };
    },
    hover(props: HeadColOwnProps, monitor: DropTargetMonitor, component: HeadColComponent): Object | void {
        if (!monitor.canDrop()) {
            return;
        }
        // ...
        props.updateDragProcess(currentDragProcess);
    },
    canDrop(props: HeadColOwnProps, monitor: DropTargetMonitor): boolean {
        return props.taskColType !== (monitor.getItem() as DraggedItem).sourceColType;
    }
};

const headColSourceCollector = (connect: DragSourceConnector, monitor: DragSourceMonitor) => ({
    dndConnectDragSource: connect.dragSource(),
    dndConnectDragPreview: connect.dragPreview(),
    dndIsDragging: monitor.isDragging()
});

const headColTargetCollector = (connect: DropTargetConnector, monitor: DropTargetMonitor) => {
    return {
        dndConnectDropTarget: connect.dropTarget(),
        dndIsOverCurrent: monitor.isOver({ shallow: true })
    };
};

再配置後、 endDragは呼び出されませんが、 dropが呼び出されることに気付きました。 これらの行は実行されません。

endDrag(props: HeadColOwnProps, monitor: DragSourceMonitor): void {
        console.debug('endDrag');
        if (!monitor.didDrop()) {
            return;
        }
        console.debug('endDrag finish');
        props.updateOrderCols((monitor.getDropResult() as DroppedResult).newOrderCols);
    }

私は何が間違っているのですか? 何か案は?

HTML5BackendをTouchBackend(https://github.com/yahoo/react-dnd-touch-backend)に置き換えました。 わたしにはできる。

私にとっては、ドロップのコールバックにブレークポイントを設定しただけでこのエラーが発生していました。 興味深いのは、すべてのブレークポイントが継続され、ブラウザーが一時停止されなかった後でも失敗することです。 ブレークポイントを削除するとすぐに、離れるとエラーが発生します。

私は同じ問題を抱えています。 このパッケージをreact-dnd-touch-backendに置き換えましたが、それは実際には問題の解決に役立ちません。 私はむしろhtml5を実行したいと思います。 イテレータによって印刷されているすべての要素にキーを設定しようとしました。

同じエラーが発生していました。 私はすべてのレンダリングのドラッグ可能なコンポーネントにHOCを再適用していたので、それらは常に異なっていたため、react-dndが混乱していました。

@hakuninはこれを解決し

それ以来、取得したすべてのDnDコードをリファクタリングしましたが、ドラッグを開始しても取得できます。 すべてのコードを単一のutilファイルに移動して構成可能にしたので、ある時点でそれが発生する理由を最終的に見つけることができるかもしれません。 私がそうするとき、それについてここに投稿します。 (私はマウス設定でTouchBackendを使用しています)

返信ありがとうございます。 このエラーは、ドラッグ中に他のエラーが発生した後にのみ発生します。その時点では、回復できないようです。 それはあなたにとっても同じですか?

ドラッグを開始するたびに文句を言います。

私の場合、アイテムがドロップされた後、endDragのコンポーネント(props、monitor、component)が未定義でした。 そのため、元のエラーが発生し、「ドロップ後にホバーを呼び出せません」というメッセージのコンソールストリームが発生していました。

このコメントのおかげで、この問題を解決することができました: https

以前に他のキャッチされていないエラーを引き起こしたときにこれに遭遇しました。他のエラーがなかった場合、このエラーはありません。

私の場合、endDragでエラーの原因となるアクション/関数を呼び出すと発生しました。 したがって、基本的にキャッチされていないエラーにより、dndがスタックしました。 endDragブロックで関数/アクションを呼び出すときにtrycatchを使用できます。
endDrag: (props, monitor) => { try { handleEndDrag(); } catch(errror) { console.error(error)} }

onDrop関数内のデバッガーステートメントも、私にとってエラーの原因でした。 それを削除するとエラーが消えますが、それなしでデバッグするのに苦労しています。

デバッガーがこのエラーをトリガーしている理由はありますか?

興味があるかどうかはわかりませんが、Electronアプリを実行しています。

この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。

このページは役に立ちましたか?
0 / 5 - 0 評価