React Redux - проблема при попытке использовать React-DnD и mapDispatchToProps

Мне было интересно, почему я не могу заставить некоторые из моих компонентов работать с использованием ReactDnD и mapDispatchToProps.

Я пытаюсь перетащить Сервисы на Клиентов, но не могу найти свои функции отправки в реквизитах в моей serviceSpec для метода endDrag.

Учитывая мой mapDispatchToProps для моего компонента Service:

const mapDispatchToProps = (dispatch) => ({
  dragService: (service) => { dispatch(dragService(service)) },
  dropService: (service, clientTarget) => { dispatch(dropService(service, clientTarget)) }
});

Функции высшего порядка для соединения вместе DragSource + Service + State + Dispatch:

var reduxConnectedService = connect(mapStateToProps, mapDispatchToProps)(Service);
export default DragSource('service', serviceSpec, collect)(reduxConnectedService);

метод render():

render (){
    const { isDragging, connectDragSource, service } = this.props;
    return connectDragSource(
      <a className="panel-block is-active">
        <CategoryIcon category={service.category}/>
        {service.name} | ${service.price}
      </a>
    )
  }

Объект spec, используемый для реализации спецификации dragSource (вот проблема):

const serviceSpec = {
  beginDrag(props) {
    return props.service;
  },
  endDrag(props, monitor, component){
    console.log(props);
  }
}

Функция console.log в endDrag просто показывает мой объект службы, потому что возвращается в функцию beginDrag:

{service: {…}}

Но мой план состоял в том, чтобы отправить действие drop Service здесь на endDrag, но я не смог. В документации сказано, что ( http://react-dnd.github.io/react-dnd/docs/api/drag-source):

beginDrag (реквизит, монитор, компонент): обязательно. Когда начинается перетаскивание, вызывается beginDrag. Вы должны вернуть простой объект JavaScript, описывающий перетаскиваемые данные. То, что вы возвращаете, является единственной доступной для целей перетаскивания информацией об источнике перетаскивания, поэтому важно выбрать минимальные данные, которые им нужно знать. Вы можете испытать желание вставить в него ссылку на компонент, но вам следует очень стараться избегать этого, потому что он соединяет источники перетаскивания и отбрасывает цели. Хорошей идеей будет вернуть что-то вроде {id: props.id} из этого метода.

Я не верю, что должен возвращать функцию drop Service (dispatch) в определении beginDrag. Поэтому после нескольких часов, пытаясь заставить его работать, я начал передавать функцию drop Service как опору непосредственно через родительский компонент (ServiceList):

{this.props.filteredServices.map((service, index) => (
     <Service service={service} key={service.name} dropService={this.props.dropService}/>
))}

Сделав так, я мог бы отправить действие drop Service на метод endDrag, как я хотел, console.log может доказать, что:

{service: {…}, dropService: ƒ}

Я мог бы заставить это работать, но я не могу понять, почему я не мог заставить это работать, используя mapDispatchToProps. Есть ли какие-либо ограничения при использовании React-DnD или я что-то не так делаю?

Любая помощь будет оценена, я не могу умереть с этим сомнением. Заранее спасибо.

1 ответ

Решение

Ваша проблема с этими двумя строками:

var reduxConnectedService = connect(mapStateToProps, mapDispatchToProps)(Service);
export default DragSource('service', serviceSpec, collect)(reduxConnectedService);

Обратите внимание на порядок: вы заверните Service в контейнер Redux. Затем вы оборачиваете контейнер Redux DragSource контейнер. Таким образом, в дереве компонентов контейнер перетаскивания является родителем контейнера Redux, что означает, что он не получает от него реквизиты Redux.

Чтобы это исправить, сделайте контейнер перетаскивания дочерним по отношению к контейнеру Redux. Вы можете сделать это, просто поменяв DragSource() а также connect() звонки:

var dragService = DragSource('service', serviceSpec, collect)(Service);
var reduxConnectedService = connect(mapStateToProps, mapDispatchToProps)(dragService);
Другие вопросы по тегам