w3resource

@apollo/react-hoc


This tutorial outlines some of the @apollo/react-hoc API reference.

Installation

npm install @apollo/react-hoc

graphql(query, [config])(component)

import { graphql } from '@apollo/react-hoc';

The graphql() function is the most important thing exported by the @apollo/react-hoc package. With this function you can create higher-order components that can execute queries and update reactively based on the data in your Apollo store. The graphql() function returns a function which will "enhance" any component with reactive GraphQL capabilities. This follows the React higher-order component pattern which is also used by react-redux's connect function.

The graphql() function may be used like this:

function TodoApp({ data: { todos } }) {
  return (
    <ul>
      {todos.map(({ id, text }) => (
        <li key={id}>{text}</li>
      ))}
    </ul>
  );
}
export default graphql(gql`
  query TodoAppQuery {
    todos {
      id
      text
    }
  }
`)(TodoApp);

You may also define an intermediate function and hook up your component with the graphql() function like this:

// Create our enhancer function.
const withTodoAppQuery = graphql(gql`query { ... }`);

// Enhance our component.
const TodoAppWithData = withTodoAppQuery(TodoApp);

// Export the enhanced component.
export default TodoAppWithData;

The graphql() function will only be able to provide access to your GraphQL data if there is a <ApolloProvider/> component higher up in your tree to provide an ApolloClient instance that will be used to fetch your data.

The behavior of your component enhanced with the graphql() function will be different depending on if your GraphQL operation is a query, a mutation, or a subscription. Go to the appropriate API documentation for more information about the functionality and available options for each type.

Before we look into the specific behaviors of each operation, let us look at the config object. The config object is the second argument you pass into the graphql() function, after your GraphQL document. The config is optional and allows you to add some custom behavior to your higher order component.

export default graphql(
  gql`{ ... }`,
  config, // <- The `config` object.
)(MyComponent);

Let's go through all of the properties that may live on your config object.

config.options

config.options is an object or a function that allows you to define the specific behavior your component should use in handling your GraphQL data.

The specific options available for configuration depend on the operation you pass as the first argument to graphql(). There are options specific to queries and mutations.

You can define config.options as a plain object, or you can compute your options from a function that takes the component's props as an argument.

Example:

export default graphql(gql`{ ... }`, {
  options: {
    // Options go here.
  },
})(MyComponent);
Copy
export default graphql(gql`{ ... }`, {
  options: props => ({
    // Options are computed from `props` here.
  }),
})(MyComponent);

config.props

The config.props property allows you to define a map function that takes the props (and optionally lastProps) added by the graphql() function (props.data for queries and props.mutate for mutations) and allows you to compute a new props (and optionally lastProps) object that will be provided to the component that graphql() is wrapping.

The function you define behaves almost exactly like mapProps from Recompose providing the same benefits without the need for another library.

config.props is most useful when you want to abstract away complex functions calls into a simple prop that you can pass down to your component.

Another benefit of config.props is that it also allows you to decouple your pure UI components from your GraphQL and Apollo concerns. You can write your pure UI components in one file and then keep the logic required for them to interact with the store in a completely different place in your project. You can accomplish this by your pure UI components only asking for the props needed to render and config.props can contain the logic to provide exactly the props your pure component needs from the data provided by your GraphQL API.

This example uses props.data.fetchMore.

export default graphql(gql`{ ... }`, {
  props: ({ data: { fetchMore } }) => ({
    onLoadMore: () => {
      fetchMore({ ... });
    },
  }),
})(MyComponent);

function MyComponent({ onLoadMore }) {
  return (
    <button onClick={onLoadMore}>
      Load More!
    </button>
  );
}

To access props that are not added by the graphql() function, use the ownProps keyword. For example:

export default graphql(gql`{ ... }`, {
  props: ({ data: { liveImage }, ownProps: { loadingImage } }) => ({
    image: liveImage || loadingImage,
  }),
})(MyComponent);

To access lastProps, use the second argument of config.props. For example:

export default graphql(gql`{ ... }`, {
  props: ({ data: { liveImage } }, lastProps) => ({
    image: liveImage,
    lastImage: lastProps.data.liveImage,
  }),
})(MyComponent);

Previous: @apollo/react-components
Next: @apollo/react-testing