Connected Higher Order Component (HOC)
Composing HOC with Connect ()
Why?
Recently, I had a use-case to connect a HOC to the Redux Store.
One form but different field level customizations for different clients.
One way to go about doing this is to Connect the components with the Redux Store and then to add appropriate disable or hide checks on the fields when the user belongs to a particular client.
In the example below- to get the customizations to disable the name and status fields for a Big Client, <DetailsFields /> and <NameSearch /> Components are connected to the Redux Store and a check in Render is added to Disable them.
I had a lot of these field-level Client customization logic baked in my components.
What I would have liked is to have one Higher Order Component take care of all these field-level customizations for different clients . So my Form- components would not have disabled or hide checks inside them depending on which client is using it.
Hence, I created a HOC <FieldWrapper />.
In <FieldWrapper />, I get the clientName from the Redux Store using connect provided by react-redux. Depending on the clientName, I disable or hide a field Component as required.
This was perfect!
All my other components did not have any client level customization checks. <FieldWrapper /> Component was the only Component responsible for all the client level customization.
But as soon as I opened my browser, I got the “Cannot call a class as a function” type error.
So, Connect function from “react-redux”, which we use to connect our components with the Redux Store when called returns a function which expects a Component. Whereas, we were giving it a HOC not a React Component Instance.
From React-Redux library when connect is called it return a function which expects a React Component.
So, how to connect our HOC with the Redux Store?
We now have connect(mapStateToProps) and our FieldWrapper both are functions which are expecting a React Component but not each other.
What we need is to pass our React <Field /> Component to <FieldWrapper /> and pass the component it returns to connect(mapStateToProps).
If we can do this, both our HOC <FieldWrapper /> and connect(mapStateToProps) will be happy as they will receive React.Component instance and with the help of javascript Closure we would have access to clientName in our HOC <FieldWrapper />.
Everything would just work!
This looks like composing both the functions like:
connect(mapStateToProps)(HOC(<Field />))
Better we can use compose from Redux.
Now, <ComposedFieldWrapper /> can be used as our connected HOC. connect(mapStateToProps) and our FieldWrapper both are happy, as both of them will get React Component Instance as input.
Final Connected HOC:
One thing to keep in mind is that dispatch prop is induced in our FieldWrapper now, as it is connected with the Redux Store using connect. ClientName prop is also not required by Field components anymore because all client level logic is in our HOC. So, we are not passing dispatch and clientName props down while passing rest of the props.
To get more updates on Javascript and React Stuff, connect with me on twitter @karanjariwala47.
Follow Practo Engineering on twitter for regular updates. If you like this article, please hit the applause icon to recommend it. This will help other Medium users find it.