visit
If you’re using in your projects you’re sure to have come across the Apollo and their GraphQL-enabled tools. One of the toolsets Apollo has introduced is Apollo-Boost (which I’ll refer to simply as Boost from here on). Boost allows for minimal Apollo Client configuration and boilerplate in you applications. Apollo Client itself is a wrapper class designed to simplify interaction with GraphQL servers (and, as we shall see, client-side GraphQL as well). They also have tool support for the React framework, among others. While the Client is framework-independent, the library has components that integrate seamlessly with Apollo Client.
Note that it is , not npm; create_react_app is the name I chose for the new project. The resulting package.json file will contain the following:
You’ll notice that there are several build scripts provided, and react-scripts is used as the application launcher. The react-scripts launcher provides a curated list of dependencies with minimal configuration. You can read about what is provided . When npm run start
is executed, it will launch a hot React server (one that relaunches when detecting code changes) and will automatically load a sample application page in your browser.
import ApolloClient from "apollo-boost";const client = new ApolloClient({ uri: "//w5xlvm3vzz.lp.gql.zone/graphql"});
The server was built using Apollo Launchpad (another GraphQL tool you should have in your belt), and you can access it online . Note that as of this writing, the Query shown in the Launchpad is wrong, and should be something like:
(I’ve cleaned up the syntax a bit from the original generated application.) The ApolloProvider is the connecting component between the React application and the GraphQL client. From within the provider, we can add Query and Mutation components in the application which operate against a context. You can think of the context as the state of the application, but one that is accessed via GraphQL scripts.
The Query component takes a GraphQL query string as a property. That query string is executed when the component is rendered, invoking a function that takes loading state, errors (if any) and a data result as parameters. What usually happens (on a good day) is that once loading is false (query data is done loading), and no errors are returned, then the data properties are passed down to child components.
Taking that query shown earlier, we can create a simple display:And then, back in the main application:
import ExchangeRates from './ExchangeRates'
const App = () => (<ApolloProvider client={client}><div className="App"><header className="App-header"><img src={logo} className="App-logo" alt="logo" /><h1 className="App-title">Welcome to React</h1></header><ExchangeRates/></div></ApolloProvider>)
You’ll notice that ExchangeRates makes its own Query, so that the component is entirely self-contained. The resulting page is no beauty, but it is accurate:Partial list of currency exchange rates relative to the dollar (USD)
const client = new ApolloClient({uri: "",clientState: {defaults: {currencyOfInterest: 'USD',}}})
The currencyOfInterest will be stored locally, on the client. We inform the query of the location through the @client directive. I change the original component layout slightly so that the original query results from the server are passed down to the ExchangeSelector via props.
{({ loading, error, data }) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (<div><header className="App-header"><ExchangeSelector data={data}/></header><ExchangeList data={data} />;</div>)}}</Query>);
Here’s a look at the new React ExchangeSelector component:
The @client designation one line 6 tells ApolloClient that the value can be found in the local cache. This value can be accessed and written to just as if it resided on the server, through Query and Mutation operations. However, since this is locally stored, it is often more convenient to update the client cache directly, using client.writeData()
as shown on line 21.