React-dnd: ¿Cómo utilizar un componente de terceros como fuente de arrastre?

Creado en 18 dic. 2015  ·  9Comentarios  ·  Fuente: react-dnd/react-dnd

Quiero usar un componente de terceros (en este caso, un <ListGroupItem> de React Bootstrap ) como fuente de arrastre. Cuando llamo connectReactSource en él, aparece un error que me dice

Ahora solo se pueden pasar nodos de elementos nativos a connectDragSource (). Puede envolver ListGroupItem en un

, o conviértalo en una fuente de arrastre o en un destino para soltar.

Sin embargo, si lo envuelvo en <div> , estropeará mi marcado y estilo porque se supone que es <li> . La otra opción es convertirlo en una fuente de arrastre, pero no veo cómo hacerlo sin editar la fuente del componente de terceros. ¿Qué es lo correcto para hacer aquí?

Comentario más útil

Ahora también tenemos este problema para buscar en Google :-)

¡Afortunadamente! :sonrisa:

Solo quiero agregar un poco de precisión, si está acostumbrado a encadenar las llamadas connect*() en sus render() s, lo mismo no funcionará con el enfoque anterior, en su lugar, debe hacer lo siguiente:

ref={instance => {
  const node = findDOMNode(instance);
  connectDragSource(node);
  connectDropTarget(node);
}}

Todos 9 comentarios

Buena pregunta. Creo que deberías poder hacer esto:

import { findDOMNode } from 'react-dom';

class DraggableListGroupItem extends Component {
  render() {
    const { connectDragSource, ...rest } = this.props;
    return (
      <ListGroupItem
        {...rest}
        ref={instance => connectDragSource(findDOMNode(instance))}
      />
    );
  }
}

export default DragSource(...)(DraggableListGroupItem);

Esto funciona porque las funciones connect*() miran lo que les pasa. Se pueden usar declarativamente (pasar un elemento DOM React y obtener un elemento DOM React a cambio) o imperativamente (llamarlos con el nodo DOM y no olvide llamarlos con null más tarde, al igual que las referencias funcionan ).

(Esto también le da la libertad de usar algún otro elemento DOM como fuente de arrastre; por ejemplo, puede consultar el nodo que obtiene de findDOMNode() . Esto debe usarse como último recurso porque es malo confiar en Estructura DOM de un componente de terceros).

Esto no funcionó para mí. El anidamiento ahora es correcto, pero el elemento no se puede arrastrar y aparece el siguiente error en la consola:

Unhandled promise rejection TypeError: (0 , _reactDom2.default) is not a function(…)

Creo que escribiste

import findDOMNode from 'react-dom';

en vez de

import { findDOMNode } from 'react-dom';

De hecho, react-dom no tiene una exportación predeterminada, por eso utilicé una exportación con nombre específica llamada findDOMNode . Más sobre la diferencia entre exportaciones predeterminadas y con nombre: http://exploringjs.com/es6/ch_modules.html

Estaba tratando de escribir un ejemplo reducido, ¡pero primero atrapaste el error!

Conozco la diferencia entre exportaciones predeterminadas y con nombre, pero no siempre me doy cuenta de cuál necesito y las herramientas de depuración no son excelentes para dar un mensaje de error que muestre lo que está sucediendo. Ahora puedo ver cómo ese mensaje de error apunta al problema a pesar de que Webpack lo ha estropeado. ¡Gracias por la lección!

PD: si tuviera que presentar una solicitud de extracción para agregar esto a los documentos (no estoy seguro de que tenga tiempo), ¿dónde lo pondría? Sería útil si el error connectDragSource apuntara a esta solución.

No estoy seguro, creo que el mensaje actual es suficientemente bueno. Ahora también tenemos este problema para buscar en Google :-)

Por cierto, releo tu pregunta y quiero dejar claro que no tienes que envolverla en <div> específicamente . El punto del mensaje de error es que connectDragSource() necesita envolver cualquier elemento DOM — <div> , <li> , o cualquier otra cosa. Solo necesita la solución anterior para los componentes personalizados.

Ahora también tenemos este problema para buscar en Google :-)

¡Afortunadamente! :sonrisa:

Solo quiero agregar un poco de precisión, si está acostumbrado a encadenar las llamadas connect*() en sus render() s, lo mismo no funcionará con el enfoque anterior, en su lugar, debe hacer lo siguiente:

ref={instance => {
  const node = findDOMNode(instance);
  connectDragSource(node);
  connectDropTarget(node);
}}

2 preguntas sobre esto:
Q1. ¿También puede usar la biblioteca de la tercera parte como un objetivo de arrastre? El caso de uso sería usar reactstrap "Container" como objetivo y soltar "Row" u otros componentes dentro de él para construir una página.
Q2. Parece que findDOMNode no funciona en componentes funcionales. ¿Cómo hacer arrastrar / soltar con algunos componentes de terceros si son funcionales?

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