Trying to wrap your head around React HOCs? Want some real world examples to look at?

Then you’ve come to the right place!

If you are completely new to React HOCs, you should read my Simple explanation of Higher-Order Components (HOC) before moving on.

Add a hidden prop to your components

This HOC adds a hidden prop to your components. When hidden is set to true, your components becomes… hidden!

Usage

const HelloWorldWithHidden = withHiddenProp ( HelloWorld ) ; < HelloWorldWithHidden hidden = { true } / >

HOC

export function withHiddenProp ( WrappedComponent ) { return class extends React . Component { render ( ) { if ( this . props . hidden ) { return null ; } else { return < WrappedComponent { ... this . props } / > ; } } } ; }

Full example

Full example on codesandbox.io

Add toggle functionality to your components

This HOC adds two props to your components: toggled and onToggle

toggled : a boolean that represents the toggle

: a boolean that represents the toggle onToggle : a function that toggles the toggled variable

Usage

const Button = ( { toggled , onToggle } ) => < button onClick = { onToggle } > { toggled ? "It's ON! :)" : "It's OFF! :(" } < / button > ; const ToggledButton = withToggle ( Button ) ; < ToggledButton / >

HOC

function withToggle ( WrappedComponent ) { return class extends React . Component { constructor ( props ) { super ( props ) ; this . onToggle = this . onToggle . bind ( this ) ; this . state = { toggled : false } ; } onToggle ( ) { this . setState ( { toggled : ! this . state . toggled } ) ; } render ( ) { return ( < WrappedComponent onToggle = { this . onToggle } toggled = { this . state . toggled } { ... this . props } / > ) ; } } ; }

Full example

Full example on codesandbox.io

Show component when feature toggle is set

Feature toggles are a powerful technique to change behavior without deploying new code.

When using this HOC, your component will only be displayed when its feature toggle is set to true.

Usage

const HelloWorldWithToggle = whenFeatureToggled ( "helloWorld" , HelloWorld ) ; < HelloWorldWithToggle / >

HOC

const featureToggles = { helloWorld : true } ; function whenFeatureToggled ( feature , WrappedComponent ) { return class extends React . Component { render ( ) { if ( ! featureToggles [ feature ] ) { return null ; } else { return < WrappedComponent { ... this . props } / > ; } } } ;

Full example

Full example on codesandbox.io

Add a loading spinner while fetching data

A common UI pattern is showing a loading spinner while data is fetched asynchronously from the backend.

This HOC shows a spinner when this.props.data is null or undefined .

Usage

const HelloWorldWithLoadingSpinner = withLoadingSpinner ( HelloWorld ) ; class HelloWorldContainer extends React . Component { constructor ( props ) { super ( props ) ; this . state = { data : null } ; setTimeout ( ( ) => this . loadingComplete ( ) , 2000 ) ; } loadingComplete ( ) { this . setState ( { data : "hello" } ) ; } render ( ) { return < HelloWorldWithLoadingSpinner data = { this . state . data } / > ; } }

HOC

function withLoadingSpinner ( WrappedComponent ) { return class extends React . Component { render ( ) { if ( ! this . props . data ) { return < Spinner / > ; } else { return < WrappedComponent { ... this . props } / > ; } } } ; }

Full example

Full example on codesandbox.io

Responsive components

If you need a responsive design you have two options: either use media queries with CSS or use JavaScript/React. There are pro and cons for each. If you go for the React solution you might want to use this HOC.

This HOC is based on this excellent solution for detecting mobile/desktop by Gosha Arinich

Usage

class HelloWorld extends React . Component { render ( ) { return this . props . isDesktop ? < h1 > Hello world from Desktop < / h1 > : < h1 > Hello world from mobile < / h1 > ; } } const HelloWorldResponsive = detectDesktopOrMobile ( HelloWorld ) ; < HelloWorldResponsive / >

HOC

function detectDesktopOrMobile ( WrappedComponent ) { return class extends React . Component { constructor ( ) { super ( ) ; this . state = { width : window . innerWidth , } ; } componentWillMount ( ) { window . addEventListener ( 'resize' , this . handleWindowSizeChange ) ; } componentWillUnmount ( ) { window . removeEventListener ( 'resize' , this . handleWindowSizeChange ) ; } handleWindowSizeChange = ( ) => { this . setState ( { width : window . innerWidth } ) ; } ; render ( ) { return < WrappedComponent isDesktop = { this . state . width > 500 } { ... this . props } / > ; } } ; }

Full example

Full example on codesandbox.io

Combining HOCs

Now we have a bunch of small composable HOCs. We can combine many HOCs on one component like this:

const Button = ( { toggled , onToggle } ) => < button onClick = { onToggle } > { toggled ? "It's ON! :)" : "It's OFF! :(" } < / button > ; const ToggledButton = whenFeatureToggled ( "myToggleButton" , withToggle ( Button ) ) ; < ToggledButton / >

As you can see, you combine HOCs by doing nested function calls. This can be a bit tricky to read and work with when having many HOCs:

hoc1 ( hoc2 ( hoc3 ( hoc4 ( Component ) ) ) )

A solution to this is using a utility library included in Redux (and Recompose) that composes HOCs:

compose ( hoc1 , hoc2 , hoc3 , hoc4 ) ( Component )

More readable and easier to work with!