React-dnd: HTML5Backend arrête de glisser lorsque des éléments du DOM apparaissent/disparaissent dans l'événement de glissement : CHROME

Créé le 1 avr. 2020  ·  3Commentaires  ·  Source: react-dnd/react-dnd

Décrivez le bogue
Nous avons un sérieux problème avec le backend html5. Nous devons générer des espaces pour guider l'utilisateur où déposer l'élément déplacé, nous voulons que ces espaces ne soient visibles que lorsque l'élément est déplacé.
Dans firefox fonctionne parfaitement mais dans chrome, les cartes lancent l'événement d'arrêt du glissement immédiatement après l'événement de démarrage du glissement.

la reproduction
https://codesandbox.io/s/react-dnd-sortable-holes-bq2oe
Chaque carte est déplaçable et lorsque l'utilisateur commence à faire glisser des espaces orange apparaît.
image

image

Dans Firefox fonctionne comme un charme, mais dans Chrome, l'événement d'arrêt est lancé immédiatement après l'événement de démarrage.

Comme vous pouvez le voir dans la console :
image

  • Système d'exploitation : [par exemple, iOS]
  • Navigateur : bogue dans la version 80.0.3987.162 de Chrome, fonctionne parfaitement dans firefox 74.0 (64 bits)

Toute aide sera vraiment appréciée, nous avons vraiment besoin de cette fonctionnalité.

Commentaire le plus utile

Notre équipe a amélioré la solution de contournement de l'état en créant un crochet personnalisé pour le fournisseur de glisser-déposer, dans tous les cas où l'un d'entre vous est confronté à ce problème, voici une solution pendant que le bogue est résolu.

https://codesandbox.io/s/react-dnd-sortable-gaps-custom-9tl13

La partie principale consiste à définir un contexte et un fournisseur pour stocker le statut de glissement.

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>
  );
};

Deuxièmement, en utilisant setTimeout dans la fonction de début de glissement, la fin envoyée est évitée.

  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
  ];

Et enfin, la valeur collectée isDragging est remplacée par la valeur de contexte.

Tous les 3 commentaires

J'ai trouvé une solution de contournement, en lisant beaucoup, pour ce problème, en définissant un délai d'attente et une variable d'état que je passe à travers les composants, je ne l'aime pas beaucoup, car dans ces cas simples, c'est facile à faire, mais complexe cas, je devrais utiliser le contexte ou quelque chose de similaire pour que tout fonctionne.
https://codesandbox.io/s/react-dnd-sortable-holes-vxeus

J'espère que vous pourrez me guider vers une meilleure solution, j'aimerais utiliser isDragging de la bibliothèque au lieu de cette solution de contournement.

Notre équipe a amélioré la solution de contournement de l'état en créant un crochet personnalisé pour le fournisseur de glisser-déposer, dans tous les cas où l'un d'entre vous est confronté à ce problème, voici une solution pendant que le bogue est résolu.

https://codesandbox.io/s/react-dnd-sortable-gaps-custom-9tl13

La partie principale consiste à définir un contexte et un fournisseur pour stocker le statut de glissement.

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>
  );
};

Deuxièmement, en utilisant setTimeout dans la fonction de début de glissement, la fin envoyée est évitée.

  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
  ];

Et enfin, la valeur collectée isDragging est remplacée par la valeur de contexte.

Quelqu'un a-t-il une solution ou une idée de correctif pour ce problème qui n'implique pas une telle solution de contournement?

Cette page vous a été utile?
0 / 5 - 0 notes