Storybook & Atomic Design - 1.14. - Apollo Provider

by Jack Pritchard

Hey! Just so you know, this article is over 2 years old. Some of the information in it might be outdated, so take it with a grain of salt. I'm not saying it's not worth a read, but don't take everything in it as gospel. If you're curious about something, it never hurts to double-check with a more up-to-date source!

GitHub - whatjackhasmade/storybook-atomic-design-react

Contribute to whatjackhasmade/storybook-atomic-design-react development by creating an account on GitHub.

In this lesson, we'll be extending our layout wrapper component to include Apollo, but first, what exactly is Apollo and why do we need it in our application?

As our future application may (in our case will) require interfacing with a GraphQL schema, we will need a method of querying and mutating information within the browser.

Enter Apollo

#

Fortunately, there is a powerful React solution named Apollo.

Apollo will act as our method of communicating with the GraphQL schema during runtime, allowing us to query and mutate our API directly within our React components.

Read more about Apollo and how it works with React at - https://www.apollographql.com/docs/react/

To get started, we'll first create a new directory named

apollo'in our
particles'directory with a single file `provider.jsx'-

- __Storybook__
- __components__
- __particles__
- __apollo__
- provider.jsx

After creating the directory and files, we'll need to install quite a few packages to support us in constructing our Apollo Provider component.

Run the following command from a console in your projects parent directory.

npm i @apollo/react-hooks apollo-boost graphql

provider.jsx

#

Finally, we will compose our Apollo Wrapper component which will allow us to tap into our GraphQL schema within any component using Apollo functions.

Again, you can think of this similar to how we constructed the ThemeProvider for our global layout component, by creating a HOC (High Order Component) which feeds data or functions to children components.


We first need to import

ApolloProvider'from
@apollo/react-hooks'to allow us to reference the provider component and pass in our client value which we'll create with the
ApolloClient'function from
apollo-boost`.

To create a new client, we will need to pass in one argument to our

ApolloClient'function, which is an object with a key of
uri'and the URL of the GraphQL API we want to interface with.

Next, we'll create our custom `ApolloWrapper'React component which will accept children (all children components in our application) and construct an ApolloProvider surrounding the component, allowing all children (including our stories) to query and mutate our external API

import React from 'react';
import { ApolloProvider } from '@apollo/react-hooks';
import ApolloClient from 'apollo-boost';

const client = new ApolloClient({
uri: '<http://celticwordpress.co.uk/graphql>',
});

const ApolloWrapper = ({ children }) => (
<ApolloProvider client={client}>{children}</ApolloProvider>
);

export default ApolloWrapper;

Then we will import our new provider to our global decorator layout wrapper (

.storybook/config.js
), and wrap all of our children components within the `ApolloWrapper'component, allowing all children to send queries and mutations to our schema.

import React from 'react';
import { addDecorator, configure } from '@storybook/react';
import { ThemeProvider } from 'styled-components';

import ApolloWrapper from '../components/particles/apollo/provider';
import GlobalStyles from '../components/particles/globalStyles';
import themeDefault from '../components/particles/themeDefault';

// automatically import all files ending in *.stories.js
configure(require.context('../components', true, /\\.stories\\.js$/), module);

const GlobalWrapper = storyFn => (
<ApolloWrapper>
<ThemeProvider theme={themeDefault}>
<GlobalStyles />
{storyFn()}
</ThemeProvider>
</ApolloWrapper>
);

addDecorator(GlobalWrapper);

My First Apollo GraphQL Query

#

To make use of our new ApolloWrapper particle functionality, I've gone ahead and included a GraphQL query in our Homepage component.

The GraphQL query interfaces with a WooCommerce WPGraphQL store and returns a list of products in the store with the value of their name (titles).

We can then use this query in our application with a

useQuery'hook, destructuring the values of
data
,
error
, and
loading'to manage our homepage layout.

If the query is still processing we will return a message of 'Loading...'.

If we hit an error with our query we get an upset error message returned.

But, but, but!

If everything went well, we'll have a JSON payload response in `data'that we can map over to return a list of products available in our store!

homepage.jsx

#
import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import { gql } from 'apollo-boost';

import Banner from '../../organisms/banner/banner';
import Carousel from '../../organisms/carousel/carousel';
import Footer from '../../organisms/footer/footer';
import Header from '../../organisms/header/header';

const EXCHANGE_RATES = gql`
query {
products {
nodes {
name
}
}
}
`;

const Homepage = ({ banner, carousel, footer, header }) => {
const { loading, error, data } = useQuery(EXCHANGE_RATES);

if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;

return (
<>
<Header {...header} />
<h2>Products</h2>
{data.products.nodes.map(({ name }) => (
<h3>{name}</h3>
))}
<Banner {...banner} />
<Carousel {...carousel} />
<Footer {...footer} />
</>
);
};

export default Homepage;

Conclusion

#

Oh boy did we cover a tonne in this lesson.

If you didn't quite understand any of the subjects we covered in this lesson, don't worry as the configuration is definitely advanced and most of the concepts go over my head at times.

Just as long as you can get your `'working then you'll be in a great place to benefit from the Apollo functionality with the use of Apollo hooks in your application.

Further Reading

#

Introduction to Apollo Client

Why Apollo Client?

Why choose Apollo Client to manage your data?

Get started with Apollo Client