Я хочу использовать сторонний компонент (в данном случае <ListGroupItem>
из React Bootstrap ) в качестве источника перетаскивания. Когда я звоню на него connectReactSource
я получаю сообщение об ошибке
Теперь в connectDragSource () можно передавать только узлы собственных элементов. Вы можете обернуть ListGroupItem в
, или превратить его в источник перетаскивания или саму цель перетаскивания.Однако, если я заключу его в
<div>
, это испортит мою разметку и стиль, потому что это должно быть<li>
. Другой вариант - превратить его в источник перетаскивания, но я не вижу, как это сделать, не редактируя источник стороннего компонента. Что здесь нужно делать?
Хороший вопрос. Думаю, у вас должно получиться это:
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);
Это работает, потому что connect*()
функции смотрят на то, что вы им передаете. Их можно использовать либо декларативно (передать элемент DOM React и получить элемент DOM React взамен), либо императивно (вызвать их с помощью узла DOM и не забудьте позже вызвать их с помощью null
- так же, как работают ссылки. ).
(Это также дает вам свободу использовать какой-либо другой элемент DOM в качестве источника перетаскивания - например, вы можете запросить узел, который вы получаете из findDOMNode()
. Это следует использовать в крайнем случае, потому что полагаться на внутренние DOM-структура стороннего компонента.)
У меня это не сработало. Вложенность теперь правильная, но элемент нельзя перетащить, и в консоли появляется следующая ошибка:
Unhandled promise rejection TypeError: (0 , _reactDom2.default) is not a function(…)
Я верю, что ты набрал
import findDOMNode from 'react-dom';
скорее, чем
import { findDOMNode } from 'react-dom';
Действительно, react-dom
не имеет экспорта по умолчанию, поэтому я использовал конкретный именованный экспорт под названием findDOMNode
. Подробнее о разнице между экспортом по умолчанию и именованным экспортом: http://exploringjs.com/es6/ch_modules.html
Я пытался написать сокращенный пример, но вы первым поймали ошибку!
Я знаю разницу между экспортом по умолчанию и именованным экспортом, но не всегда замечаю, какой из них мне нужен, а инструменты отладки не очень хороши для выдачи сообщения об ошибке, показывающего, что происходит. Теперь я вижу, как это сообщение об ошибке указывает на проблему, несмотря на то, что она была исправлена Webpack. Спасибо за урок!
PS: если бы я отправил запрос на перенос, чтобы добавить это в документы (не уверен, что у меня будет время), где бы я его поместил? Было бы полезно, если бы ошибка connectDragSource указывала на это решение.
Не уверен, я думаю, что текущее сообщение достаточно хорошее. Теперь у нас тоже есть проблема с поиском в Google :-)
Между прочим, я перечитал ваш вопрос и хочу отметить, что вам совершенно не обязательно заключать его в <div>
специально . Суть сообщения об ошибке заключается в том, что connectDragSource()
должен обернуть любой элемент DOM - <div>
, <li>
или что-то еще. Вам понадобится только описанный выше обходной путь для пользовательских компонентов.
Теперь у нас тоже есть проблема с поиском в Google :-)
К счастью! :ухмылка:
Просто хочу добавить немного точности, если вы привыкли connect*()
вызовы render()
s, то же самое не будет работать с вышеуказанным подходом, вместо этого вам нужно выполнить следующий:
ref={instance => {
const node = findDOMNode(instance);
connectDragSource(node);
connectDropTarget(node);
}}
2 вопроса по этому поводу:
Q1. Можете ли вы также использовать третью библиотеку в качестве цели перетаскивания. Сценарий использования - использовать reactstrap «Контейнер» в качестве цели и отбрасывать «Row» или другие компоненты внутри него для создания страницы.
Q2. Похоже, что findDOMNode не работает с функциональными компонентами. Как сделать перетаскивание с некоторыми сторонними компонентами, если они работают?
Самый полезный комментарий
К счастью! :ухмылка:
Просто хочу добавить немного точности, если вы привыкли
connect*()
вызовыrender()
s, то же самое не будет работать с вышеуказанным подходом, вместо этого вам нужно выполнить следующий: