React Redux - 尝试使用 React-DnD 和 mapDispatchToProps 时遇到问题

React Redux - Trouble trying to use React-DnD and mapDispatchToProps

我想知道为什么我不能使用 ReactDnD 和 mapDispatchToProps 让我的一些组件工作。

我正在尝试将服务拖放到客户端,但我无法在 endDrag 方法的 serviceSpec 的道具中找到我的调度函数。

考虑我的服务组件上的 mapDispatchToProps:

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

用于实现dragSource规范的spec对象(这里是问题所在):

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

endDrag 函数中的 console.log 仅显示我的服务对象,因为正在 returned on beginDrag 函数中:

{service: {…}}

但我的计划是在 endDrag 上发送操作 dropService,但我不能。文档说 (http://react-dnd.github.io/react-dnd/docs/api/drag-source):

beginDrag(props, monitor, component): Required. When the dragging starts, beginDrag is called. You must return a plain JavaScript object describing the data being dragged. What you return is the only information available to the drop targets about the drag source so it's important to pick the minimal data they need to know. You may be tempted to put a reference to the component into it, but you should try very hard to avoid doing this because it couples the drag sources and drop targets. It's a good idea to return something like { id: props.id } from this method.

我认为我不应该 return beginDrag 定义中的 dropService(dispatch) 函数。因此,在尝试使其工作数小时后,我开始将 dropService 函数作为道具直接通过父组件 (ServiceList) 传递:

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

通过这种方式我可以像我想要的那样在 endDrag 方法上调度 dropService 操作,console.log 可以证明:

{service: {…}, dropService: ƒ}

我可以让它工作,但我不明白为什么我不能使用 mapDispatchToProps 让它工作。使用 React-DnD 时有任何限制还是我做错了什么?

任何帮助将不胜感激,我不能带着这个疑问死去。提前谢谢你。

你的问题出在这两行:

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

注意顺序:将 Service 包装到 Redux 容器中。然后用 DragSource 容器包装 Redux 容器。因此,在组件树中,拖动容器是 Redux 容器的 parent,这意味着它不会从它那里接收 Redux props。

要解决这个问题,请将拖动容器设为 Redux 容器的 child。您可以通过简单地交换 DragSource()connect() 调用来做到这一点:

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