React-dnd: Using redux connect alongside DropTarget mapping

Created on 9 Feb 2016  ·  5Comments  ·  Source: react-dnd/react-dnd

I'm trying to figure out the correct way to hook up redux to my component that also happens to be a drop target.

export default DropTarget(dragTypes, storyTarget, collect)(connect(mapStateToProps)(StoryEditor));

This is how I am connecting them at the moment, it seems to work, but I wanted to verify that this is correct.

Most helpful comment

I would do it like this:

import { compose } from 'redux'

export default compose(
  DropTarget(dragTypes, storyTarget, collect),
  connect(mapStateToProps)
)(StoryEditor);

All 5 comments

I would do it like this:

import { compose } from 'redux'

export default compose(
  DropTarget(dragTypes, storyTarget, collect),
  connect(mapStateToProps)
)(StoryEditor);

In the React DnD docs @gaearon uses _.flow to decorate a component with multiple higher level components. So if I am reading this right we actually can just use the compose function from redux, correct?

@ekeric13 Redux's compose is identical to _.flow with reversed arguments. That is,

compose(f, g, h)(x) === flow(h, g, f)(x) === f(g(h(x)))

@gaearon Using compose works fine for me, but I noticed the documentation for compose says non right most functions passed to compose should expect a single parameter, yet we're able to pass three arguments to DropTarget. Why does this work?

compose(...functions)

Composes functions from right to left.

This is a functional programming utility, and is included in Redux as a convenience.
You might want to use it to apply several store enhancers in a row.

Arguments

(arguments): The functions to compose. Each function is expected to accept a single parameter. Its return value will be provided as an argument to the function standing to the left, and so on. The exception is the right-most argument which can accept multiple parameters, as it will provide the signature for the resulting composed function.

BuilderArea.propTypes = {
  addPanel: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
  panels: state.panels
});

export default compose(
  DropTarget(Types.PANEL_CARD, builderAreaTarget, (connect, monitor) => ({
    connectDropTarget: connect.dropTarget(),
    isOver: monitor.isOver()
  })),
  connect(
    mapStateToProps,
    { addPanel }
  )
)(BuilderArea);
Was this page helpful?
0 / 5 - 0 ratings