Higher Order What?
Tags: javascript, react, refactoring, testing
Published: 2017-01-06 14:05:34

---
title: Higher Order What?
published: true
description: Higher Order Components
cover_image: 
tags: javascript, react, refactoring, testing
---

So, since it's 2017 you probably using one of these fancy new _component_ based frameworks, like __React__ and you read about all this _Higher Order Component_ (HOC) talk last year, but you still don't understand what it's all about. You maybe read about these _Higher Order Functions_ (HOF) and ask yourself, what these pesky functional programmers up to. Are they trying to ravage a perfectly object oriented concept again? I can assure you, they mean you no harm... this time!

For OOP people to understand, HOCs are an alternative to inheritence. They allow you to do composition in a dynamic way.

    // Example adding basic HTTP request functions to a component via inheritence

    class HttpConnectedComponent extends Component {...}

    class UserList extends HttpConnectedComponent {...}

    class Application {
      render() {
        return <UserList/>
      }
    }

The problem here is obvious, you now got a new base class and always have to extend it if you want to have HTTP functionallity, if you got a bunch of other _base classes_ it gets messy rather quick and your component is now tighly coupled to the base class.

HOCs allow you to evade this problem. _They are simply functions that take the definition of a component and return a new definition of a component_. This can be a bit ... puzzling, I know, but bare with me.

Lets go to HOFs first, they are rather simple. They are functions that take functions as arguments and/or return functions.

     // This HOF takes a function and creates a new one, that will return a 
     // stringified version of the first functions result.

     function stringifyResult(f) {
       return function (arg) { f(arg).toString() }
     }

     function timesTwo(num) { return num * 2 }

     const timesTwoAsString = stringifyResult(timesTwo)

     timesTwo(4) // -> 8
     timesTwoAsString(4) // -> "8"

As you can see in the function definiton of `stringifyResult`, you could also modify the arguments that are passed to `f`, not just the result of `f`. So you could do a variety of behvaiour extensions to any function with this _pattern_.

The idea with HOCs is now, to do this with components. The point is, that you end up with a _enhanced_ version of your basic component, without extending some other base classes and you can simply use this new version everywhere in your app, if needed. Or you could use it at specific points in your app, to modify the behaviour of a component depending on the context, without handling this behavior change in the component itself (authentication/authorization, etc). 

You could, for example, code a `UserList` component that gets an array of users as prop (in the case of React) and then _enhance_ this with a `connectHttp` HOC, that will "wrap" the `UserList` in another component, that will request the user data from the server and pass it into the right prop on completion.

    // React Example

    // This function creates a new class definition on every call
    // It takes an URL, a prop name and a Component class(!) not an object.
    function connectHttp(url, prop, Comp) {

      return class extends Component {

        state = {result: null}

        // When it's in the DOM, get the data
        componentDidMount() {
          getData(url).then(result => this.setState({result}))
        }

        // render a placeholder while the data is null
        // render the Component with the data in the right prop, when its not null
        render() {
          const {result} = this.state
          // creating a new props object, that passes the props of "this" component 
          // through AND adds the data of the request
          const props = {...this.props, [prop]: result}

          return result? <Comp {...props}/> : <span>Loading...</span>
        }

      }

    }

    // Simple user list
    // Can be tested stand-alone
    // Is completely oblivious to the "source" of the data
    function UserList({users=[]}) {
      return (
        <ul>
          {props.users.map(user => <li>{user.name}</li>)}
        </ul>
      )
    }

    // The wrapped component class
    // Can now be used to create lists, that fetch their data themself
    const ConnectedUserList = connectHttp('/users', 'users', UserList)
     
    ...
    
    <Application>
      <ConnectedUserList/>
    </Application>

In this example, the HOC allows you to _enhance_ other component definitions dynamically. It creates a central point that handles the HTTP connection and the other components can be much simpler, which eases testing and refactoring. You could write a new HOC, that gets the data via WebSockets and none of your other components will be the wiser. 

This behaviour could also be achieved with a "regular" component, that simply passes data down to its child components, whatever they are. The difference is, that you would have to _explicitly_ wrap your component every time, which can be rather cumbersome in bigger applications.

Wrapping components like this is only one way to use HOC, another way is to "extend" your target component. The new component inherits from your component instead of your component inherting from the new one. This gives you more control over the components behaviour. You could override (lifecycle) methods for example. This also flattens the component hierarchy, because just "one" component is constructed and not the wrapper and the target component.