2017-08-24 4 views
0

J'essaie de comprendre some code Réagir écrit en ESnext (décorateurs). Je sais comment convertir les décorateurs de ESnext à la syntaxe ES6Comment convertir la syntaxe du décorateur en ES6?

// ESnext 
function collect(connect, monitor) { 
    return { 
    connectDragSource: connect.dragSource(), 
    isDragging: monitor.isDragging() 
    } 
} 

@DragSource(Types.CARD, cardSource, collect) 
export default class Card extends React.Component { 
    render() { 
    const { id } = this.props; 
    const { isDragging, connectDragSource } = this.props; 

    return connectDragSource(
     <div> 
     I am a draggable card number {id} 
     {isDragging && ' (and I am being dragged now)'} 
     </div> 
    ); 
    } 
} 

ES6

// ES6 
function collect(connect, monitor) { 
    return { 
    connectDragSource: connect.dragSource(), 
    isDragging: monitor.isDragging() 
    }; 
} 

class Card extends React.Component { 
    render() { 
    const { id } = this.props; 
    const { isDragging, connectDragSource } = this.props; 

    return connectDragSource(
     <div> 
     I am a draggable card number {id} 
     {isDragging && ' (and I am being dragged now)'} 
     </div> 
    ); 
    } 
} 

export default DragSource(Types.CARD, cardSource, collect)(Card); 

Mais je suis coincé comment convertir ce code ES6?

function collectDrop(connect) { 
    return { 
    connectDropTarget: connect.dropTarget(), 
    }; 
} 

function collectDrag(connect, monitor) { 
    return { 
    connectDragSource: connect.dragSource(), 
    isDragging: monitor.isDragging() 
    }; 
} 

@DropTarget(ItemTypes.CARD, cardTarget, collectDrop) 
@DragSource(ItemTypes.CARD, cardSource, collectDrag) 
export default class Card extends Component { 
    static propTypes = { 
    connectDragSource: PropTypes.func.isRequired, 
    connectDropTarget: PropTypes.func.isRequired, 
    index: PropTypes.number.isRequired, 
    isDragging: PropTypes.bool.isRequired, 
    id: PropTypes.any.isRequired, 
    text: PropTypes.string.isRequired, 
    moveCard: PropTypes.func.isRequired, 
    }; 

    render() { 
    const { text, isDragging, connectDragSource, connectDropTarget } = this.props; 
    const opacity = isDragging ? 0 : 1; 

    return connectDragSource(connectDropTarget(
     <div style={{ ...style, opacity }}> 
     {text} 
     </div>, 
    )); 
    } 
} 
+0

Ce que vous avez posté n'est pas ES7. ES7 (ES2016) ne prend pas en charge les décorateurs. –

+0

@FelixKling merci pour la clarification! –

Répondre

1

Parce que vous avez deux décorateurs plus élevés des composants commande (HOC), vous devez les combiner et envelopper votre classe lors de l'exportation avec ces deux (DropTarget et DragSource). Si vous utilisez la bibliothèque redux, vous pouvez utiliser sa fonction utilitaire compose qui combine plusieurs HOC et enveloppe la classe avec. Le code que vous devez vous concentrer sur est à la fin du code ci-dessous:

import { compose } from 'redux' 

function collectDrop(connect) { 
    return { 
    connectDropTarget: connect.dropTarget(), 
    }; 
} 

function collectDrag(connect, monitor) { 
    return { 
    connectDragSource: connect.dragSource(), 
    isDragging: monitor.isDragging() 
    }; 
} 

class Card extends Component { 
    static propTypes = { 
    connectDragSource: PropTypes.func.isRequired, 
    connectDropTarget: PropTypes.func.isRequired, 
    index: PropTypes.number.isRequired, 
    isDragging: PropTypes.bool.isRequired, 
    id: PropTypes.any.isRequired, 
    text: PropTypes.string.isRequired, 
    moveCard: PropTypes.func.isRequired, 
    }; 

    render() { 
    const { text, isDragging, connectDragSource, connectDropTarget } = this.props; 
    const opacity = isDragging ? 0 : 1; 

    return connectDragSource(connectDropTarget(
     <div style={{ ...style, opacity }}> 
     {text} 
     </div>, 
    )); 
    } 
} 

const enhance = compose(
    DropTarget(ItemTypes.CARD, cardTarget, collectDrop), 
    DragSource(ItemTypes.CARD, cardSource, collectDrag) 
) 

export default enhance(Card) 

Ou (si vous ne l'utilisez Redux) vous pouvez les combiner comme ça:

// Comment this part out 
/* const enhance = compose(
    DropTarget(ItemTypes.CARD, cardTarget, collectDrop), 
    DragSource(ItemTypes.CARD, cardSource, collectDrag) 
) 

export default enhance(Card)*/ 

// and change to this 

const dropTargetHOC = DropTarget(ItemTypes.CARD, cardTarget, collectDrop) 
const dragSourceHOC = DragSource(ItemTypes.CARD, cardSource, collectDrag) 

export default dropTargetHOC(dragSourceHOC(Card)) 
1

documentation dactylographiée offre bonne explication de decorator composition (décorateurs TS et ES decorators proposal sont identiques pour la plupart):

Lorsque plusieurs décorateurs appliquent à une seule déclaration, leur Evaluati est similaire à la composition des fonctions en mathématiques. Dans ce modèle , lors de la composition des fonctions f et g, le composite résultant (f ∘ g) (x) est équivalent à f (g (x)).

En tant que tel, les étapes suivantes sont effectuées lors de l'évaluation de plusieurs décorateurs sur une seule déclaration dactylographiée:

Les expressions pour chaque décorateur sont évaluées de haut en bas. Les résultats sont ensuite appelés en tant que fonctions du bas vers le haut.

Il est censé être:

export default DropTarget(ItemTypes.CARD, cardTarget, collectDrop)(
    DragSource(ItemTypes.CARD, cardSource, collectDrag)(Card); 
); 

Ceci est censé être utilisé à des fins et non académiques production. Le code original n'est pas ES6 mais JSX, il nécessite toujours un transteteur (Babel) pour être converti en JavaScript valide. Il n'y a donc aucune raison de ne pas utiliser toutes les fonctionnalités que Babel peut offrir, y compris les décorateurs.

+0

Merci! , l'explication est ce dont j'avais besoin! –