React-dnd: monitor.isDragging () a veces devuelve falso cuando debería devolver verdadero

Creado en 9 jul. 2015  ·  12Comentarios  ·  Fuente: react-dnd/react-dnd

Cuando se utilizan dos o más listas ordenables interoperables, monitor.isDragging () devuelve falso a veces cuando debería devolver verdadero al arrastrar un elemento de un contenedor a otro.

Configuración: a partir de la demostración ordenable simple, agregue otro contenedor y un conjunto de objetos ordenables. Las tarjetas deben poder arrastrarse de un contenedor a otro, clasificarse dentro de su propio contenedor y clasificarse a medida que se arrastran de un contenedor a otro.

El problema ocurre al mover una tarjeta de un contenedor a otro. El componente de la tarjeta depende de la propiedad isDragging (inyectada por el decorador DragSource) para determinar la opacidad, sin embargo, cuando el elemento se arrastra de un contenedor a otro, el monitor global cambia el sourceId que ya no coincide con el componente arrastrado y termina regresando falso para llamadas a isDragging cuando debería devolver verdadero.

Dado que la fuente de arrastre ya requiere una clave única global consistente por cada objeto arrastrable (otras cosas realmente se comportan mal si las claves de su componente arrastrable cambian en cualquier momento), ¿puede el código usar esa clave al designar el sourceId para que arrastrar desde un contenedor funcione correctamente?

Avísame si necesitas ver el código de ejemplo. Mi código que demuestra este problema se basa en la demostración ordenable simple.

Comentario más útil

Para que isDragging funcione en el árbol de componentes, implemente manualmente isDragging en su fuente de arrastre.

const ingredientSource = {
    beginDrag(props) {
        return { ingredient: props.ingredient };
    },
    isDragging(props, monitor) {
        return props.ingredient === monitor.getItem().ingredient;
    }
};

Ver DragSource docs :

isDragging(props, monitor) : Opcional. De forma predeterminada, solo se considera que arrastra la fuente de arrastre que inició la operación de arrastre. Puede anular este comportamiento definiendo un método isDragging . Podría devolver algo como props.id === monitor.getItem().id . Haga esto si el componente original se puede desmontar durante el arrastre y luego "resucitar" con un padre diferente. Por ejemplo, cuando mueve una tarjeta a través de las listas en un tablero Kanban, desea que mantenga la apariencia arrastrada, aunque técnicamente, el componente se desmonta y se monta uno diferente cada vez que lo mueve a otra lista. _Nota: No puede llamar a monitor.isDragging() dentro de este método.

¿Esto ayuda?

Todos 12 comentarios

@amoenk Sí, necesitaremos un código de ejemplo para ayudarlo.

¡Gracias por tu ayuda! Aquí está el ejemplo de trabajo: http://notlouieagain.com/~amoenk/dnd/

Y este enlace para navegar por el código desagregado: http://notlouieagain.com/~amoenk/dnd/js/

Oh, incluí el código de demostración ordenable simple original allí también mientras estaba depurando, pero los componentes importantes son Ingredient e IngredientGroup.

Eché un vistazo a su código y parece que no puedo encontrar el componente DnDStudy . ¿Puedes mostrarme tu código completo y solo el tuyo? Puede eliminar el código de demostración.

Código de demostración eliminado, el componente DnDStudy es un componente de la página aquí: http://notlouieagain.com/~amoenk/dnd/js/pages/DnDStudy.react.js

Ok, eché un vistazo y creo que puede ser un problema debido a las claves de IngredientGroup dentro de DnDStudy . En lugar de confiar en el índice de la matriz, intente usar una identificación única similar a la de Ingredient dentro de IngredientGroup .

Código actualizado, pero sigue siendo el mismo problema.

Está bien. Entonces me equivoqué.

@gaearon ¿puedes ayudar?

Para que isDragging funcione en el árbol de componentes, implemente manualmente isDragging en su fuente de arrastre.

const ingredientSource = {
    beginDrag(props) {
        return { ingredient: props.ingredient };
    },
    isDragging(props, monitor) {
        return props.ingredient === monitor.getItem().ingredient;
    }
};

Ver DragSource docs :

isDragging(props, monitor) : Opcional. De forma predeterminada, solo se considera que arrastra la fuente de arrastre que inició la operación de arrastre. Puede anular este comportamiento definiendo un método isDragging . Podría devolver algo como props.id === monitor.getItem().id . Haga esto si el componente original se puede desmontar durante el arrastre y luego "resucitar" con un padre diferente. Por ejemplo, cuando mueve una tarjeta a través de las listas en un tablero Kanban, desea que mantenga la apariencia arrastrada, aunque técnicamente, el componente se desmonta y se monta uno diferente cada vez que lo mueve a otra lista. _Nota: No puede llamar a monitor.isDragging() dentro de este método.

¿Esto ayuda?

¡Funciona perfectamente! Debe haber perdido eso en los documentos.

¡Gracias por toda tu ayuda! Cerraré el ticket.

No hay problema. Feliz de ayudar.

meh! Los enlaces a http://notlouieagain.com/ no responden ...

Encontré la causa raíz de mi problema. Tuve que dejar de usar DragDropContextProvider para envolver mis DropTargets y DragSources. Vea el ejemplo a continuación.
http://react-dnd.github.io/react-dnd/docs-drag-drop-context-provider.html

export default class YourApp {
    render() {
        return (
            <DragDropContextProvider backend={HTML5Backend}>
                /* ... */
            </DragDropContextProvider>
        )
    }
}

En cambio, tuve que usar DragDropContext para envolver toda mi clase como se muestra a continuación.
http://react-dnd.github.io/react-dnd/docs-drag-drop-context.html

class YourApp {
    /* ... */
}
export default DragDropContext(HTML5Backend)(YourApp)

Esto me solucionó de inmediato el problema.

¿Fue útil esta página
0 / 5 - 0 calificaciones