バグを説明する
html5backendに深刻な問題があります。 ドラッグされた要素をドロップする場所をユーザーにガイドするために、いくつかのギャップを生成する必要があります。これらのギャップは、要素がドラッグされている間のみ表示されるようにします。
Firefoxでは完璧に機能しますが、Chromeでは、カードはドラッグ開始イベントの直後にドラッグ停止イベントを開始します。
再生
https://codesandbox.io/s/react-dnd-sortable-holes-bq2oe
各カードはドラッグ可能であり、ユーザーがドラッグを開始するとオレンジ色のギャップが表示されます。
Firefoxではチャームのように機能しますが、Chromeでは開始イベントの直後に停止イベントが開始されます。
あなたがコンソールで見ることができるように:
どんな助けでも本当にありがたいです、私たちは本当にこの機能が必要です。
この問題の回避策を見つけました。この問題については、コンポーネントを通過するタイムアウトと状態変数を設定します。これらの単純なケースでは簡単ですが、複雑であるため、あまり好きではありません。場合によっては、すべてを機能させるためにコンテキストなどを使用する必要があります。
https://codesandbox.io/s/react-dnd-sortable-holes-vxeus
より良い解決策をご案内していただければ幸いです。この回避策の代わりに、ライブラリのisDraggingを使用したいと思います。
私たちのチームは、ドラッグアンドドロッププロバイダーのカスタムフックを作成する状態の回避策を改善しました。この問題に直面した場合は、バグを解決しながら解決策を示します。
https://codesandbox.io/s/react-dnd-sortable-gaps-custom-9tl13
主な部分は、ドラッグステータスを保存するためのコンテキストとプロバイダーの定義で構成されます。
const DndContext = React.createContext([{}, () => {}]);
const DndCustomProvider = props => {
const [state, setState] = useState({ dragging: false });
return (
<DndProvider backend={props.backend}>
<DndContext.Provider value={[state, setState]}>
{props.children}
</DndContext.Provider>
</DndProvider>
);
};
次に、ドラッグ開始関数でsetTimeoutを使用すると、ディスパッチされた終了が回避されます。
const [context, setContext] = useContext(DndContext);
const [collected, dragRef] = useDrag({
...,
begin: monitor => {
setTimeout(() => {
setContext(() => ({ dragging: true }));
}, 0);
if (begin) {
begin(monitor);
}
},
end: (item, monitor) => {
setContext(() => ({ dragging: false }));
if (end) {
end(item, monitor);
}
},
...
});
return [
{
...collected,
isDragging: context.dragging
},
dragRef
];
そして最後に、isDraggingで収集された値は、コンテキスト値で上書きされます。
このような回避策を伴わないこの問題のパッチの解決策またはアイデアを持っている人はいますか?
最も参考になるコメント
私たちのチームは、ドラッグアンドドロッププロバイダーのカスタムフックを作成する状態の回避策を改善しました。この問題に直面した場合は、バグを解決しながら解決策を示します。
https://codesandbox.io/s/react-dnd-sortable-gaps-custom-9tl13
主な部分は、ドラッグステータスを保存するためのコンテキストとプロバイダーの定義で構成されます。
次に、ドラッグ開始関数でsetTimeoutを使用すると、ディスパッチされた終了が回避されます。
そして最後に、isDraggingで収集された値は、コンテキスト値で上書きされます。