Seeing the light with React.Context - Multiple React.Context in a class component
Tags: react, context, class, javascript
Published: 2021-06-21 12:35:30

---
title: Seeing the light with React.Context - Multiple React.Context in a class component
published: true
description: A question I quickly had to ask ask myself was: "How do you have multiple contexts in a React class component?" - useContext to the rescue
tags: react, context, class, javascript
cover_image: https://bs-uploads.toptal.io/blackfish-uploads/blog/post/seo/og_image_file/og_image/16097/react-context-api-4929b3703a1a7082d99b53eb1bbfc31f.png
---

> A question I quickly had to ask ask my self was: "How do you have multiple contexts in a React class component?" - useContext to the rescue

I've been working as a software engineer for +10 years where I basically only have been doing CRUD. At the end of last year I got an offer to join a company that has a physical piece of hardware as their product, with a react native app as client for this hardware. It didn't take me long to decide. It's a great company, with a great vision and roadmap.

The codebase wasn't how I imagined. All components was class components, written in the "old" react way using class components with `.bind(this)`. A global context that was one big mess. No TypeScript - or PropTypes for the components.

## Step 1 - The cleanup
One of my first pull requests was adding typescript and a testing framework and started to refactor most of the presentation components into functional components. In that process I also added some tests.

### Step 2 - Cleanup App.js
Step 2 was splitting the HUGE (~800 lines including the global AppContext) `App.js` into multiple components and separating the AppContext into a file by it self. After doing this the whole app started to perform much better. Step 2 was now done.

### Step 3 - Cleaning up the AppContext
Code was already starting to look better. The app was performing better. The next step was a bit more cleanup in the AppContext. I wanted to extract some of the AppContext into separate contexts - I'd rater have less lines and many file than one very large file with many lines.

One question I quickly had to ask ask my self was: "How do you have multiple contexts in a React class component?". I've spend some time reading up on this and didn't like the approach that was mentioned in the [react documentation - Consuming Multiple Contexts](https://reactjs.org/docs/context.html#consuming-multiple-contexts). I'm a lazy developer and it just seemed like too much work and hard to maintain.

I've been working with Redux before and thought that I could use the same approach as Redux. Use a Higher Order Component to inject the context into the props of the component.

Instead of making a new HOC for each context I wanted some generic that could be used for all my new contexts and all components.

### Step 4 - The `withContext` HOC
So how should I go about creating this. I wanted to inject the values of the context into the component- that part was clear.

#### Let me present `useContext`
```tsx
import React, { useContext, ComponentType, Context, Component } from 'react'

export const withContext = <Props extends Record<string, any>>(contextName: string, context: Context<any>, WrappedComponent: ComponentType<Props>) =>
  (p: Props) => {
    return (
      <WrappedComponent
        {...{
          [contextName]: useContext(context),
          ...p
        }}
      />
    )
  }
```

### Example
```js
class MyClassComponent extends Component {
  render() {
    return (
      <Text>This is my class component</Text>
    )
  }
}

export default withContext(
    'connection',
    ConnectionContext,
    MyClassComponent
)
```

This works very well and is very easy to implement.
- The first parameter of the HOC is the prop name that the context should have.
- The second parameter name is the actual context
- The third parameter is the component that the context should be injected to.

### Conclusion
Using `withContext` will allow me to grab `this.props.connection.isOnline` to check if the phone is connected to the internet or not. To inject multiple contexts into my component I can use something like `compose` to loop thru all `withContext` and apply them to all of my class components.