Just started to incorporate recompose into my work flow, and I'm loving it so far. One thing I noticed is that the "compose" util is compared to traditional compose functions and lodash's flowRight, in which the functions are applied from right to left. It seems like recompose's "compose" util applies the functions from left to right. If that is the case, it might be worth updating the docs to say that.
It applyes functions in the same order as lodash, you can even use lodash compose to compose recompose HOCs.
And here is the recompose magic, as every function returns component, so having React tree their looks like applied in the flow order.
Just take a piece of paper and write this on it.
Ok, I can see the difference. It builds a HOC by running the functions from right to left, but during execution, the props are passed from left to right.
As a simple example
const a = x => x * 2
const b = x => x + 2
const param = 1;
a(b(param)); // it's compose result is 6
const a = fn => x => fn(x * 2);
const b = fn => x => fn(x + 2);
const param = 1;
a(b(x=>x))(param); // it is the same compose function as above but result is === 4
Just to add a real life example as documentation :
const contentPageData = compose(
mapProps(({ match }) => ({
contentPageID: ((match || {}).params || {}).contentPageID,
})),
graphql(
gql`
query ContentPage($id: ID!) {
ContentPage(id: $id) {
id
title
slug
content
}
}
`,
{
options: ({ contentPageID }) => ({ variables: { id: contentPageID } }),
}
),
spinnerWhileLoading,
errorIfError,
connect({
actions: [contentPageStore, ['setCurrentPageContent']],
})
)
See how mapProps() creates the prop contentPageID, then graphql() uses that prop to fetch with the right params.
Then the functions spinnerWhileLoading and errorIfError use props that the graphql() hoc injected.
Basically, when composing HOCs, think the same order as usual code:
any value one HOC uses has to be created / passed by previous HOCs.
What if two of the HOC want the instance of main Component to operate?
what do you mean the main Component ? The component wrapped by the HOCs ?
Well the whole composed HOC operates on the wrapped component, but each HOC operates on the component modified by the HOCs below it.
HOCs can:
function enhancer(WrappedComponent) {
return class EnhancedComponent extends React.Component {
render() {
return <WrappedComponent {...this.props} />
}
};
}
(check this for more details on render hijacking)
So basically any HOC can operate on the main component as long as the HOCs that operated before it (the ones below/right in the argument order) didn't modify it too much in a way that would make the next HOC error (that's on you as the programmer to watch out for).
Most helpful comment
As a simple example