React-dnd: ¿Cómo depurar "No se puede llamar al hover tras soltar"?

Creado en 19 abr. 2016  ·  24Comentarios  ·  Fuente: react-dnd/react-dnd

Hola,
uno de mis compañeros de trabajo puede romper de alguna manera el estado del monitor y cree que está suspendido a pesar de que el mouse está arriba y le da esto:

screenshot 2016-04-19 16 34 56

¿Alguna idea sobre dónde empezar a depurar? No puedo reproducirlo y él lo ve una vez a la semana.
Estoy usando el backend táctil cambiado para manejar los eventos del mouse también con algunos ajustes.

triage wontfix

Comentario más útil

También tengo este problema: mi situación es tal que el componente React es tanto el destino de colocación como la fuente de arrastre. Cuando tengo dos componentes, puedo arrastrar y soltar una vez antes de que arroje el error anterior. Cuando tengo tres, funciona sin errores. ¿Supongo que tiene algo que ver con los múltiples contextos en un solo componente?

Todos 24 comentarios

Así que investigué el problema de JS y descubrí que antes de este error, se produjo un error desde una devolución de llamada definida por el usuario cuando se supone que debe ocurrir la caída, lo que luego podría haber roto el estado del monitor / tienda.

También tengo este problema: mi situación es tal que el componente React es tanto el destino de colocación como la fuente de arrastre. Cuando tengo dos componentes, puedo arrastrar y soltar una vez antes de que arroje el error anterior. Cuando tengo tres, funciona sin errores. ¿Supongo que tiene algo que ver con los múltiples contextos en un solo componente?

Tuve este problema y encontré una solución para mi caso de uso particular anoche.

Para el contexto, estaba representando una lista de DragSources, y si alguno de ellos se colocaba en un DropTarget, se eliminaría de la lista de DragSources y el DropTarget se reemplazaría con un componente que representa el contenido del DragSource.

Una parte esencial de esta funcionalidad de arrastrar y soltar (es un componente para hacer coincidir 'categorías' con elementos) fue una función para agregar elementos a la lista DragSource, que simplemente reemplazaría el elemento colocado con un DragSource y lo agregaría nuevamente a DragSources lista.

image

Ahora, esta excepción solo ocurrió cuando colocaría elementos en todas las categorías y eliminaría al menos uno (no cuando la lista no estaba completa y eliminaría uno y lo agregaría nuevamente). Entonces llegué a la conclusión de que la lista DragSources nunca podría tener cero hijos para que esto ocurriera (posiblemente debido a que el elemento contenedor desapareció, pero no tuve tiempo suficiente para probar esto). Para mitigar esto, en lugar de eliminar elementos de la lista DragSources en la ubicación, simplemente establezco su estilo en display: none

Es difícil de explicar, pero espero que esto ayude.

Estoy experimentando el mismo efecto que @PendragonDevelopment. Mi lista comienza con un elemento, se le agrega un segundo y luego se puede reorganizar. Solo puede reorganizar los dos elementos una vez antes de que comience a ver errores de Javascript, y nunca podrá volver a ordenarlos.

Yo también tengo este problema
No sé por qué, pero después de la primera reordenación, veo estos errores

Tengo el mismo error aquí.

Después de comparar un poco el ejemplo de demostración y el mío, descubrí que cuando hago un ciclo en los componentes, uso la clave de matriz para configurar el componente tanto la clave como el índice y en la demostración solo configuran el índice Sortable / Simple / Container.js y la clave es fija.

¡Lo hice y funcionó!

La clave debe ser de valor fijo porque si no lo es, la referencia al componente se pierde después del reordenamiento de la matriz.

Cuando haya creado y adjuntado dinámicamente componentes DnD, debe usar alguna biblioteca o tal vez Date.now() lo hará para generar claves únicas para cada componente.

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

row.id es único para cada componente

No entiendo por qué funciona, pero usar mi model.id en lugar de una clave aleatoria generada por node-uuid's v4 solucionó. Al menos ya no recibo errores.

La clave de reparación no resolvió mi problema.
Este era mi codigo

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

Después de cada acción eliminada, estaba mapeando todos los elementos y recibía el mismo error.
Y cambié mi condición a

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

y está resuelto. Creo que, nuevamente, el montaje es la razón de este error.

Me encontré con este mismo error.

Mi caso de uso fue:

  • Mismo DragSource y DragTarget componente
  • Al soltar, quería navegar a una ruta

Resulta que endDrag ( DragSource método) se activa después de drop ( DropTarget método). Estaba manejando la navegación de ruta dentro de drop que estaba rompiendo el estado del monitor.

Moví esa lógica a endDrag para solucionarlo. La refactorización implicó verificar si la caída se completó con monitor.didDrop() , pero no estuvo tan mal.

Yo también tengo este problema. Mi caso es tal que el componente es tanto el destino de colocación como la fuente de arrastre. Intenté usar el método endDrag y traté de usar backend parcheado (https://gist.github.com/nickpresta/eb5cce69d650db4c2795). No resolvió este problema.

mi componente:

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

Ejemplo de uso:

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

Configuración del decorador:

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

Noté que después de la reordenación endDrag no se llama, pero se llama drop . Estas líneas nunca se ejecutan:

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

¿Qué estoy haciendo mal? ¿Algunas ideas?

Reemplacé HTML5Backend por Touch Backend (https://github.com/yahoo/react-dnd-touch-backend). Esto funciona para mi.

Para mí, recibí este error solo por tener puntos de interrupción establecidos en la devolución de llamada en la caída. Lo interesante es que fallaría incluso después de que se continuaran todos los puntos de interrupción y el navegador no se detuviera. Tan pronto como eliminé los puntos de interrupción, el error cuando estaba fuera.

Estoy teniendo el mismo problema. Reemplazó este paquete con react-dnd-touch-backend pero eso realmente no ayuda a resolver el problema. Prefiero ejecutar html5. Intenté establecer claves en todos los elementos que está siendo impreso por un iterador.

Recibí el mismo error. Estaba volviendo a aplicar un HOC en los componentes arrastrables en cada renderizado, por lo que siempre eran diferentes, lo que confundía a react-dnd.

@hakunin , ¿resolvió esto (también recibo este error solo después de que se haya producido otro error de tiempo de ejecución)?

Desde entonces, he refactorizado todo el código DnD que tengo y todavía lo obtengo cuando empiezo a arrastrar. Ahora que moví todo el código a un solo archivo util y lo hice configurable, es posible que finalmente pueda encontrar la razón por la que sucede en algún momento. Publicaré sobre esto aquí cuando lo haga. (Estoy usando TouchBackend en la configuración del mouse por cierto)

Gracias por la respuesta. Solo recibo este error después de que se produzca algún otro error al arrastrar, momento en el que parece irrecuperable. es lo mismo para ti?

El mío se queja cada vez que empiezo a arrastrar.

Mi caso fue que el componente en endDrag (props, monitor, component) no estaba definido después de que se eliminó el elemento. Entonces eso estaba causando mi error original que llevó a la secuencia de la consola de mensajes "No se puede llamar al pasar el mouse después de soltar".

He podido resolver este problema gracias a este comentario: https://github.com/react-dnd/react-dnd/issues/431#issuecomment -317219509

Me encontré con esto cuando causé otro error no detectado antes. No hay este error cuando no hubo otros errores.

En mi caso, sucedió cuando en endDrag llamo a alguna acción / función que causa un error. Así que básicamente un error no detectado hizo que dnd se atascara. puede usar try catch al llamar a alguna función / acción en el bloque endDrag.
endDrag: (props, monitor) => { try { handleEndDrag(); } catch(errror) { console.error(error)} }

Una declaración de depuración dentro de la función onDrop también fue la fuente del error para mí. Eliminarlo hace que el error desaparezca, pero luego me cuesta depurar sin él.

¿Alguna idea de por qué el depurador está activando este error?

No estoy seguro de si es de algún interés, pero estoy ejecutando una aplicación de Electron.

Este problema se ha marcado automáticamente como obsoleto porque no ha tenido actividad reciente. Se cerrará si no se produce más actividad. Gracias por sus aportaciones.

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