Higher Order With Context
Tags: javascript, react, refactoring, testing
Published: 2017-01-13 13:45:57

---
title: Higher Order With Context
published: true
description: Why higher order componets really matter
cover_image: 
tags: javascript, react, refactoring, testing
---

In my [last post](https://dev.to/kayis/higher-order-what) I wrote about higher order components (HOC) as a way to decouple components from services. In this I will explain their use with the help of the _context_ in React. This will make the last example a bit more practical.

If you used React you have probably seen a component structure like this at the root of the application:

    <ServiceProviderA>
      <ServiceProviderB>
        <Application/>
      </ServiceProviderB>
    </ServiceProviderA>

And then later some component to be defined like this:

    const List = props =>
      <ul>
        {props.items.map(i => <li>{i}</li>)}
      </ul>

    const ConnectedList = connectServiceA(List)

or even

    const ConnectedList = connectServiceB(connectServiceA(List))


In this example the `connectService` functions are HOCs. They modify the `List` definition OR (more common) wrap the `List` in another component, that provides the service. Often they don't have names that remind you on a connection between the HOCs and the services they `connect`.

Famous example is _Redux_ which is often used with in cooperation with `react-redux` to provide a React application with a Redux store. On the application root you got something like

    <Provider store={store}>
      <Application/>
    </Provider>

And then somewhere there are some components defined like this:

    const List = props =>
      <ul>
        {props.items.map(i => <li>{i}</li>}
      </ul>

    const ConnectedList = connect(state => ({items: state.items})(List)

Here the defined Redux store will be _provided_ to the application and later it will be _connected_ to a component. When seeing this the first time, it is not immediately obvious that they work together, that's why I wrote the first example more generic.

Anyway, what is happening here? Something gets provided, something gets connected and than what? How is it provided and connected?

Well, we know about the _connect_ part, it's a HOC, it somehow connects the _plain_ component with a service. Okay, but how "somehow"???

The HOC connect the service through the only interface components have, the `props`!

In the examples, the List needs an array in `props.items`, this is the only part of the, potentially big, `props` object it interacts with.

The next question is: Where does it get the service, which will be connected to the right prop?

From __The Context__!

I lied when I said, components just have the _props_ interface. In fact they got two interfaces. The `props` and the `context`. The `props` always get delivered by the parent component. The `context` instead, can get delivered by _any_ ancestor component. Like `ServiceProviderA` in our example.

But React now doesn't simply pass the context to every child component, you have to explicitly ask for it. And this _asking_ is what you can implement in a HOC.

But first, how to get data into the context in the first place? How do these `Provider` components do it?

First the provider component, that you will use at your root, needs a `getChildContext` method, that will get service/data somehow. Second, it needs `childContextTypes` to tell React _what_ it provides.

    class ItemProvider extends React.Component {

      // provide something usable, while the data is loading
      state = {items: []}

      // after added into the DOM, get some data
      componentDidMount() {
        getItemsFromService(this.props.url)
        .then(items => this.setState({items}))
      }

      // if someone down the element tree needs our context data
      // this method will be called
      getChildContext() {
        return {
          items: this.state.items,
        }
      }

    }

    // This tells React that this component provides an array for components down 
    // the tree in context.items
    ItemProvider.childContextTypes = {
      items: React.PropTypes.array,
    }

Now if we wrap some component with this provider, all the components down that tree can access its data without passing it through all of them manually via `props`. And this is _access of the context_ is what we will do via HOC. So the HOC tells React, which part of the `context` it wants and then plugs it into the wrapped components `props`.

So how does the HOC look like?

    const connectItems = (targetProp, WrappedComponent) => {

      // the context will be passed as the second argument to a component function
      const ItemComponent = (props, context) => {

        // the connection happens here!
        // props of this HOC will be merged with the items of the context
        // and passed down to the wrapped component
        const newProps = {...props, [targetProp]: context.items}

        return <WrappedComponent {...newProps}/>

      }

      // This tells React, which part of the context this component wants
      ItemComponent.contextTypes = {
        items: React.PropTypes.array,
      }

      return ItemComponent

    }

So, nothing new about HOCs here. The component tells React what it wants and then passes this data to its "wrapped" component. Here I used a stateless component definition for the HOC, because it doesn't do much, but you could use a component class too, if you need additional functionallity. Then the context would reside in `this.context`.

So to wrap it up, lets connect a component.

    const List = props =>
      <ul>
        {props.items.map(i => <li>{i}</li>)}
      </ul>

    // first argument is the target prop
    // it's where the items from context shold be passed to
    const ConnectedList = connectItems('items', List)


Now we have a `List` component, that simply relies on an items prop, it can be tested easily and used with different data sources later.

And we have a `ListWithItems` that will render the `List` but also passes it data it got through the context.

Lets use this in an application:

    <ItemProvider url={'/source/for/items'}>
      <div>
        <div>
          <h2>A List of Items</h2>
          <List style={{color: 'red'}} items={['x', 'y']}/>
          <h2>A List of Server Items</h2>
          <ConnectedList style={{color: 'blue'}}/>
        </div>
      </div>
    </ItemProvider>

At the root of the application is the `ItemProvider`, that uses its `url` prop, to gather some items from a service after it was renderd.

Then the application has a bunch of div's for layout.

And somewhere deep inside the application the lists get rendered, one uses simply the data provided directly via `props`. The other one gets its data from the `context`. They can still use other props, like `style` or `className`.

__Conclusion__

HOCs are a handy way to keep special behaviour out of your components, make them simpler, more resuable and testable. Teamed up with `context` they provide an easy way for dependency injection like service provision.

If you're writing a medium to large sized React application, chances are you already met this pattern all over the place, but know you know how to implement it yourself.