2017-07-01 3 views
0

Je suis assez nouveau sur React et Redux et très nouveau sur rea-dnd, et je pense que je suis en train de faire quelque chose de vraiment incorrect ici. Bien qu'il existe d'autres publications similaires, je ne peux pas vraiment trouver de solution.L'action Redux ne se déclenche pas avec move-dnd

Je travaille sur une application de carte Kanban qui est quelque peu basée sur celle trouvée à https://survivejs.com/react/implementing-kanban/drag-and-drop/ bien que cette version utilise Alt.js et j'utilise Redux. Le problème: lorsque vous faites glisser un composant, la fonction d'action est appelée mais pas la casse dans le réducteur (MOVE_TICKET). Cela semble être le cas quel que soit le contenu de la fonction d'action.

J'ai lié l'action à un événement click et dans ce cas, l'action et le réducteur ont fonctionné comme prévu. Cela m'amène à penser que cela doit être un problème avec la façon dont j'ai configuré le composant Ticket avec les fonctions 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) 

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 (où chaque composant de Billet est)

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

} 

Si quelqu'un peut voir où je vais mal, je pourrais vraiment utiliser une aide.

Répondre

0

Vous ne connectez pas l'action moveTicket au répartiteur redux.

Vous devez faire quelque chose comme:

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

Le second paramètre à connect est appelé mapDispatchToProps, qui fera le dispatch(actionFn) pour vous.

Vous pouvez nommer l'action liée différemment, par ex.

@connect((store) => { 
    return { 
    columns: store.columns.columns 
    }; 
}, {connectedMoveTicket: moveTicket}) 
// then use this.props.connectedMoveTicket 
+0

Merci pour cela, je semble aller dans la bonne direction maintenant, mais où dois-je connecter mapDispatchToProps? après {moveTicket}, ou ailleurs? –