Redux动作不会在使用react-dnd移动时触发

时间:2017-07-01 16:28:24

标签: reactjs redux react-dnd

我对React和Redux很新,而且反应很新,而且我认为我在这里做了一些非常不正确的事情。虽然还有其他类似的帖子,但我找不到解决方案。

我正在开发一个Kanban板应用程序,该应用程序有点基于在https://survivejs.com/react/implementing-kanban/drag-and-drop/找到的应用程序,尽管该版本使用Alt.js而我正在使用Redux。

问题:拖动组件时,会调用action函数,但是reducer中的case(MOVE_TICKET)不是。无论动作功能的内容如何,​​似乎都是这种情况。

我将操作链接到click事件,在这种情况下,action和reducer按预期工作。这让我觉得我使用dnd函数设置Ticket组件的方式一定是个问题。

Ticket.js:

    import React from "react" 
    import {compose} from 'redux';
    import { DragSource, DropTarget } from 'react-dnd';
    import ItemTypes from '../constants/ItemTypes';
    import { moveTicket } from "../actions/ticketsActions"


    const Ticket = ({
        connectDragSource, connectDropTarget, isDragging, isOver, onMove, id, children, ...props
    }) => {
      return compose (connectDragSource, connectDropTarget)(
        <div style={{
          opacity: isDragging || isOver ? 0 : 1
        }} { ...props } className = 'ticket'>
          <h3 className = 'summary'> { props.summary } </h3>
          <span className = 'projectName'> { props.projectName }</span>
          <span className = 'assignee'> { props.assignee } </span>
          <span className = 'priority'> { props.priority } </span>
        </div>
      );
    };

    const ticketSource = {
      beginDrag(props) {
        return {
            id: props.id,
          status: props.status
        };
      }
    };

    const ticketTarget = {
      hover(targetProps, monitor) {
        const targetId = targetProps.id;
        const sourceProps = monitor.getItem();
        const sourceId = sourceProps.id;
        const sourceCol = sourceProps.status;
        const targetCol = targetProps.status;

        if(sourceId !== targetId) {
          targetProps.onMove({sourceId, targetId, sourceCol, targetCol});
        }
      }
    };

    export default compose(
        DragSource(ItemTypes.TICKET, ticketSource, (connect, monitor) => ({
          connectDragSource: connect.dragSource(),
          isDragging: monitor.isDragging()
        })),
        DropTarget(ItemTypes.TICKET, ticketTarget, (connect, monitor) => ({
          connectDropTarget: connect.dropTarget(),
          isOver: monitor.isOver()
        }))
    )(Ticket)

ticketsReducer.js:

export default function reducer(state={
    tickets: [],
    fetching: false,
    fetched: false,
    error: null,
  }, action) { 

    switch (action.type) {
      case "MOVE_TICKET": {
        return [{...state, tickets: action.payload}]

      } 
    }
    return state
}

ticketsActions.js

import store from '../store';


export function moveTicket({sourceId, targetId, sourceCol, targetCol}) {

    const columns = Object.assign({}, store.getState().tickets.tickets)    
    const sourceList = columns[sourceCol];
    const targetList = columns[targetCol];
    const sourceTicketIndex = sourceList.findIndex(ticket => ticket.id == sourceId);
    const targetTicketIndex = targetList.findIndex(ticket => ticket.id == targetId);

    if(sourceCol === targetCol){
      var arrayClone = sourceList.slice();
      arrayClone.splice(sourceTicketIndex, 1);
      arrayClone.splice(targetTicketIndex, 0, sourceList[sourceTicketIndex]);

      columns[sourceCol] = arrayClone;
    }

    return function(dispatch){
      dispatch({type: "MOVE_TICKET", payload: columns});
      }

}

Column.js(呈现每个Ticket组件)

import React from "react"
import uuid from "uuid"
import { connect } from "react-redux"
import ColumnsContainer from "./ColumnsContainer"
import Ticket from "./ticket"
import { moveTicket } from "../actions/ticketsActions"

@connect((store) => {
  return {
    columns: store.columns.columns
  };
})
export default class Column extends React.Component {

    console(){
        console.log(this)
    }

    render(){

        const tickets = this.props.tickets.map((ticket, id) => 
            <Ticket 
                key = {uuid.v4()}
                id={ticket.id}
                summary = { ticket.summary }
                assignee = { ticket.assignee }
                priority = { ticket.priority }
                projectName = { ticket.displayName }
                onMove={ moveTicket }
                status= { ticket.status }
            /> 
        )

        return(
            <div key = {uuid.v4()} className = { this.props.className }>
                <h2 key = {uuid.v4()}>{ this.props.title }</h2>
                <ul key = {uuid.v4()}>{ tickets }</ul>
            </div>
        )
    }

}

如果有人能看到我出错的地方,我真的可以使用一些帮助。

1 个答案:

答案 0 :(得分:0)

您没有将@connect((store) => { return { columns: store.columns.columns }; }, {moveTicket}) export default class Column extends React.Component { // ... // use this.props.moveTicket instead of moveTicket 操作连接到redux的调度程序。

您必须执行以下操作:

connect

mapDispatchToProps的第二个参数称为dispatch(actionFn),它将为您执行@connect((store) => { return { columns: store.columns.columns }; }, {connectedMoveTicket: moveTicket}) // then use this.props.connectedMoveTicket

您可能希望以不同方式命名绑定操作,例如

response = easygui.enterbox("What is your favorite ice cream flavor?")