React-dnd: Comment utiliser un composant tiers comme source de drag ?

Créé le 18 déc. 2015  ·  9Commentaires  ·  Source: react-dnd/react-dnd

Je souhaite utiliser un composant tiers (dans ce cas un <ListGroupItem> de React Bootstrap ) comme source de glissement. Quand j'appelle connectReactSource dessus, j'obtiens une erreur me disant

Seuls les nœuds d'éléments natifs peuvent désormais être transmis à connectDragSource(). Vous pouvez soit envelopper ListGroupItem dans un

, ou en faire une source de glissement ou une cible de dépôt elle-même.

Cependant, si je l'enveloppe dans un <div> , cela va gâcher mon balisage et mon style car il est censé être un <li> . L'autre option consiste à le transformer en source de glissement, mais je ne vois pas comment le faire sans modifier la source du composant tiers. Quelle est la bonne chose à faire ici?

Commentaire le plus utile

Maintenant, nous avons aussi ce problème pour googler :-)

Heureusement! :sourire:

Je veux juste ajouter un peu de précision, si vous avez l'habitude d'enchaîner les appels connect*() dans vos render() s, la même chose ne fonctionnera pas avec l'approche ci-dessus, à la place vous devez faire le Suivant:

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

Tous les 9 commentaires

Bonne question. Je pense que tu devrais pouvoir faire ça :

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

Cela fonctionne parce que les fonctions connect*() regardent ce que vous leur transmettez. Ils peuvent être utilisés soit de manière déclarative (passer un élément DOM React et obtenir un élément DOM React en retour), soit de manière impérative (appelez-les avec le nœud DOM et n'oubliez pas de les appeler avec null plus tard - tout comme les refs fonctionnent ).

(Cela vous donne également la liberté d'utiliser un autre élément DOM comme source de glissement - par exemple, vous pouvez interroger le nœud que vous obtenez à partir de findDOMNode() . Cela devrait être utilisé en dernier recours car il est mauvais de s'appuyer sur interne Structure DOM d'un composant tiers.)

Cela n'a pas fonctionné pour moi. L'imbrication est maintenant correcte mais l'élément n'est pas déplaçable et j'obtiens l'erreur suivante dans la console :

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

je crois que tu as tapé

import findDOMNode from 'react-dom';

plutôt que

import { findDOMNode } from 'react-dom';

En effet react-dom n'a pas d'export par défaut, c'est pourquoi j'ai utilisé un export nommé spécifique appelé findDOMNode . En savoir plus sur la différence entre les exportations par défaut et nommées : http://exploringjs.com/es6/ch_modules.html

J'étais en train d'essayer d'écrire un exemple réduit mais vous avez d'abord attrapé le bogue !

Je connais la différence entre les exportations par défaut et nommées, mais je ne remarque pas toujours de laquelle j'ai besoin et les outils de débogage ne sont pas très efficaces pour afficher un message d'erreur indiquant ce qui se passe. Je peux voir maintenant comment ce message d'erreur pointe vers le problème même s'il a été mutilé par Webpack. Merci pour la leçon !

PS : si je devais déposer une pull request pour l'ajouter à la doc (pas sûr d'avoir le temps), où le mettrais-je ? Cela aiderait si l'erreur connectDragSource pointait vers cette solution.

Pas sûr, je pense que le message actuel est assez bon. Maintenant, nous avons aussi ce problème pour googler :-)

Au fait, j'ai relu votre question et je veux faire remarquer que vous n'avez absolument pas besoin de l'envelopper spécifiquement dans <div> . Le point du message d'erreur est que connectDragSource() doit envelopper n'importe quel élément DOM— <div> , <li> , ou toute autre chose. Vous n'avez besoin de la solution de contournement ci-dessus que pour les composants personnalisés.

Maintenant, nous avons aussi ce problème pour googler :-)

Heureusement! :sourire:

Je veux juste ajouter un peu de précision, si vous avez l'habitude d'enchaîner les appels connect*() dans vos render() s, la même chose ne fonctionnera pas avec l'approche ci-dessus, à la place vous devez faire le Suivant:

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

2 questions à ce sujet :
Q1. Pouvez-vous également utiliser la bibliothèque 3ème partie comme cible de déplacement. Le cas d'utilisation consisterait à utiliser le "Container" de la sangle de réaction comme cible et à déposer "Row" ou d'autres composants à l'intérieur pour créer une page
Q2. On dirait que findDOMNode ne fonctionne pas sur les composants fonctionnels. Comment faire glisser/déposer avec certains composants tiers s'ils sont fonctionnels ?

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