Skip to Content

React, Apollo and the Current User HoC

Posted on One min read

It’s often necessary to access the current user throughout the various components that make up a React app. For a recent project that used Apollo, I created a higher order component (based on this post by jcarva) that allows me to extend other components with this functionality (as opposed to passing the user prop around or whatever).

import React, { Component } from 'react';
import PropTypes from 'prop-types'
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
import { withRouter } from 'react-router';

const currentUserQuery = gql`
  query {
    viewer {
      id, email, role, organisation {
        id, name
      }
    }
  }
`;

export default (ComponentToExtend) => {
  class CurrentUserHOC extends Component {
    render () {
      const currentUserData = this.props.currentUser;

      if (currentUserData.loading) {
        return false;
      }

      return (
        <ComponentToExtend
          { ...this.props }
          currentUser={ currentUserData.viewer }
        />
      )
    }
  }

  CurrentUserHOC.contextTypes = {
    router: PropTypes.object.isRequired
  };

  return graphql(currentUserQuery, {
    name: 'currentUserData',
    options: { fetchPolicy: 'cache-first' }
  })(withRouter(CurrentUserHOC));
};

This component can then be used to enrich a UI component as follows:

import currentUser from './currentUser';

class UserViewInterface extends Component {
  render () {
    return (
      <div>
        { this.props.currentUser.email }
      </div>
    );
  }
}

export default currentUser(UserView)