0

我对 React 和 Redux 很陌生,对 react-dnd 也很陌生,我认为我在这里做的事情非常不正确。尽管还有其他类似的帖子,但我无法在其中找到解决方案。

我正在开发一个看板应用程序,该应用程序有点基于https://survivejs.com/react/implementing-kanban/drag-and-drop/上的应用程序,尽管该版本使用 Alt.js 并且我正在使用还原。

问题:当拖动一个组件时,动作函数被调用,但减速器(MOVE_TICKET)中的情况不是。无论动作函数的内容如何,​​似乎都是这种情况。

我将动作链接到点击事件,在这种情况下,动作和减速器按预期工作。这使我认为这一定是我使用 dnd 函数设置 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)

ticketReducer.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
}

门票Actions.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>
        )
    }

}

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

4

1 回答 1

0

您没有将moveTicket操作连接到 redux 的调度程序。

您必须执行以下操作:

@connect((store) => {
  return {
    columns: store.columns.columns
  };
}, {moveTicket})
export default class Column extends React.Component {
// ... 
// use this.props.moveTicket instead of moveTicket

的第二个参数connect被称为mapDispatchToProps,它会dispatch(actionFn)为你做的。

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

@connect((store) => {
  return {
    columns: store.columns.columns
  };
}, {connectedMoveTicket: moveTicket})
// then use this.props.connectedMoveTicket
于 2017-07-01T16:59:37.727 回答