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.
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?
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);
Most helpful comment
I would do it like this: