React HOCs (higher order components)
Created: 2018-04-18 16:07:03 -0700 Modified: 2018-08-10 14:24:39 -0700
Passing static parameters to an HOC (reference)Section titled Passing static parameters to an HOC (reference)
If you want to specify parameters that never change to an HOC, you can do so like this:
By doing things this way, you don’t have to use “bind” or anything.
Note that you definitely don’t want to do this with dynamic properties. For that, see this section.
Updating an HOC from the wrapped componentSection titled Updating an HOC from the wrapped component
Suppose you have a HOC to handle dragging DOM elements. You want to do something like this:
However, the InventoryItem should only be considered draggable when some condition is true (e.g. the shopkeeper is selling it at the time).
In these cases, you may think that you should update the wrapper (the HOC) from the wrapped component, but it’s better to just have the HOC call a function in the child:
If you’re going to do this, then it’s best not to just assume that the wrapped component has any functions used. The best way to do this is to make use of PropTypes, but the component itself has to implement the functions rather than having them be passed in as props. HiDeoo made a CodeSandbox for me here demonstrating how you would manifest these, but I added one extra feature to it (componentOptionallyImplements). Note that HiDeoo suggested that I follow the same paradigm of React for using “isRequired” (reference).
The definitions of componentImplements and componentOptionallyImplements are here:
The reasons why this is really helpful is because:
- The wrapper can define what’s required as opposed to the wrapped component needing to add in something extra.
- We get one consistent place to comment all of the props that the wrapper may expect (even if they’re optional).
Using a reference to a child of the wrapped component from the HOCSection titled Using a reference to a child of the wrapped component from the HOC
[14:22] HiDeoo: If [you wrote the HOC] & [you’re using] React > 16.3 You can use the new ref system with React.createRef & specially React.forwardRef https://reactjs.org/docs/forwarding-refs.html
[14:24] HiDeoo: Also, React.createRef() is now the recommended API to use for refs but callback refs are still supported
In the HOC:
From the wrapped component:
HiDeoo: Adam13531 In a more advanced way, that’s what react-dnd is doing with a this.props.connectDropTarget(element) http://react-dnd.github.io/react-dnd/docs-drop-target-connector.html
Bypassing writing a component with the same props everywhere by using HoC (reference)Section titled Bypassing writing a component with the same props everywhere by using HoC (reference)
I ran into a problem where there was a component that was used from many different containers. For example, I have a header component that has functions like “settings”, “store”, and “logout”, and I didn’t want to have to do this from every single page:
HiDeo suggested that I do this:
Anywhere you can use a decorator to get this new actions as props
Or the basic way by wrapping
HiDeoo: I use that a lot for example for notifications, I have a Notifications HoC and in any component that need to raise a notificaiton, I use the @withNotifications decorator and can use this.props.addError(‘something went wrong’) in the component
I asked about the situation where I have exactly the same header in each page:
HiDeoo: Either have its own container or decorators + HoC but if you have 30+ header, forgetting the HoC wrapping in one may screw everything up ^^
HiDeoo: And instead of rendering <Header /> you render <HeaderContainer /> which then render <Header /> with all the proper props
Passing props from Redux via HOCSection titled Passing props from Redux via HOC
Sometimes you want a higher-order component that provides some Redux state to the wrapped component:
Note that if you only want to pass specific properties, you can just change how mapStateToProps looks: