React Redux-尝试使用React-DnD和mapDispatchToProps遇到麻烦

时间:2019-02-26 13:13:21

标签: javascript reactjs redux react-dnd

我想知道为什么不能使用ReactDnD和mapDispatchToProps使某些组件正常工作。

我试图将Services拖放到Clients,但是在endDrag方法的serviceSpec上的props中找不到我的调度函数。

考虑在“服务”组件上使用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仅显示我的服务对象,因为在beginDrag函数中返回了该对象:

{service: {…}}

但是我的计划是在endDrag上将动作dropService调度到此处,但是我不能。该文档说(http://react-dnd.github.io/react-dnd/docs/api/drag-source):

  

beginDrag(属性,监视器,组件):必需。当拖动   开始时,将调用beginDrag。您必须返回一个普通的JavaScript对象   描述要拖动的数据。您的回报是唯一的   可用于拖放目标的有关拖动源的信息,因此   选择他们需要知道的最少数据非常重要。你可能   试图将对组件的引用放入其中,但是您应该   尽量避免这样做,因为它会耦合阻力源   并放下目标。最好返回{{id:   props.id}。

我不认为我应该在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时有什么限制吗?还是我做错了什么?

任何帮助将不胜感激,我不能因这个疑问而死。预先谢谢你。

1 个答案:

答案 0 :(得分:1)

您的问题在于以下两行:

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

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

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

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