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?
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?
Comentários muito úteis
Felizmente! :sorriso:
Só quero acrescentar um pouco de precisão, se você está acostumado a encadear as chamadas
connect*()
em seusrender()
s, o mesmo não funcionará com a abordagem acima, em vez disso, você precisa fazer o Segue: