Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exporting React component with multiple HOC wrappers?

I have a React component that displays styled text, and I want to have it load a network resource, listen for WebSocket input, and display notifications. In order to do this, I write Higher Order Component wrapper functions for each of these: withResource, withSocket, and withNotifications.

When exporting the component, is this correct?

class TextComponent extends React.Component {
  ...
}

export default withResource(withSocket(withNotifications(TextComponent)))
like image 746
superhawk610 Avatar asked Feb 01 '18 18:02

superhawk610


3 Answers

You can use compose from redux or recompose. For example:

Redux

import { compose } from 'redux'

export default compose(
  withResource,
  withSocket,
  withNotifications
)(TextComponent)

Recompose

import { compose } from 'recompose'

export default compose(
  withResource,
  withSocket,
  withNotifications
)(TextComponent)
like image 123
mersocarlin Avatar answered Nov 18 '22 12:11

mersocarlin


It's called functional composition and it has mathematical background (that causes y and x variables naming and reversed execution of functions). It decreases complexity of the way how you call written functions by eliminating variables extra definition and deep level of function wrapage.

Write it by yourself or use from a library like: lodash, rambda, redux, etc.

const compose = (...rest) => x => rest.reduceRight((y, f) => f(y), x)

Usage with first class functions:

const increment = (numb) => numb + 1
const multiplyBy = (multiplyNum) => (num) => multiplyNum * num

compose(increment, multiplyBy(3), increment)(4)// 4 > 5 > 15 > 16

Usage with higher order components:

compose(withRouter, withItems, withRefs)(Component) 
like image 33
Purkhalo Alex Avatar answered Nov 18 '22 11:11

Purkhalo Alex


Another simple solution can be to do this in three steps, simply putting the HOC components on top of each other like this:

const firstHOC = withNotifications(TextComponent);
const secondHOC = withSocket(firstHOC);
export default withResource(secondHOC);
like image 7
Danielh Avatar answered Nov 18 '22 12:11

Danielh