React-dnd: Como usar um componente de terceiros como fonte de arrasto?

Criado em 18 dez. 2015  ·  9Comentários  ·  Fonte: react-dnd/react-dnd

Quero usar um componente de terceiros (neste caso, <ListGroupItem> do React Bootstrap ) como fonte de arrasto. Quando eu chamo connectReactSource nele, recebo uma mensagem de erro informando-me

Apenas nós de elementos nativos agora podem ser passados ​​para connectDragSource (). Você pode envolver ListGroupItem em um

, ou transformá-lo em uma fonte de arrastar ou um destino de soltar em si.

No entanto, se eu envolvê-lo em <div> , ele bagunçará minha marcação e estilo porque deveria ser <li> . A outra opção é transformá-lo em uma fonte de arrastar, mas não vejo como fazer isso sem editar a fonte do componente de terceiros. Qual é a coisa certa a fazer aqui?

Comentários muito úteis

Agora também temos esse problema para pesquisar no Google :-)

Felizmente! :sorriso:

Só quero acrescentar um pouco de precisão, se você está acostumado a encadear as chamadas connect*() em seus render() s, o mesmo não funcionará com a abordagem acima, em vez disso, você precisa fazer o Segue:

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

Todos 9 comentários

Boa pergunta. Acho que você deve ser capaz de fazer isso:

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

Isso funciona porque as funções connect*() olham para o que você as passa. Eles podem ser usados ​​declarativamente (passar um elemento DOM React e obter um elemento DOM React em retorno) ou imperativamente (chamá-los com o nó DOM e não se esqueça de chamá-los com null mais tarde - assim como os refs funcionam )

(Isso também lhe dá a liberdade de usar algum outro elemento DOM como a fonte de arrastar - por exemplo, você pode consultar o nó obtido em findDOMNode() . Isso deve ser usado como último recurso porque é ruim depender de recursos internos Estrutura DOM de um componente de terceiros.)

Isso não funcionou para mim. O aninhamento agora está correto, mas o elemento não pode ser arrastado e recebo o seguinte erro no console:

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

Eu acredito que você digitou

import findDOMNode from 'react-dom';

ao invés de

import { findDOMNode } from 'react-dom';

Na verdade, react-dom não tem uma exportação padrão, é por isso que usei uma exportação nomeada específica chamada findDOMNode . Mais sobre a diferença entre exportações padrão e nomeadas: http://exploringjs.com/es6/ch_modules.html

Eu estava tentando escrever um exemplo reduzido, mas você pegou o bug primeiro!

Eu sei sobre a diferença entre exportações padrão e nomeadas, mas nem sempre noto qual eu preciso e as ferramentas de depuração não são boas em fornecer uma mensagem de erro que mostra o que está acontecendo. Posso ver agora como essa mensagem de erro aponta para o problema, embora tenha sido mutilado pelo Webpack. Obrigado pela lição!

PS: se eu fosse registrar uma solicitação de pull para adicionar isso aos documentos (não tenho certeza se terei tempo), onde eu colocaria? Seria útil se o erro connectDragSource apontasse para esta solução.

Não tenho certeza, acho que a mensagem atual é boa o suficiente. Agora também temos esse problema para pesquisar no Google :-)

A propósito, eu reli sua pergunta e quero deixar claro que você absolutamente não precisa envolvê-la em <div> especificamente . O ponto da mensagem de erro é que connectDragSource() precisa envolver qualquer elemento DOM— <div> , <li> ou qualquer outra coisa. Você só precisa da solução alternativa acima para componentes personalizados.

Agora também temos esse problema para pesquisar no Google :-)

Felizmente! :sorriso:

Só quero acrescentar um pouco de precisão, se você está acostumado a encadear as chamadas connect*() em seus render() s, o mesmo não funcionará com a abordagem acima, em vez disso, você precisa fazer o Segue:

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

2 perguntas sobre isso:
T1. Você também pode usar a biblioteca de 3ª parte como um destino de arrasto. O caso de uso seria usar o reactstrap "Container" como um destino e soltar "Row" ou outros componentes dentro dele para construir uma página
2º trimestre. Parece que findDOMNode não funciona em componentes funcionais. Como arrastar / soltar alguns componentes de terceiros se eles forem funcionais?

Esta página foi útil?
0 / 5 - 0 avaliações