Skip to content

Instantly share code, notes, and snippets.

@necccc
Created October 20, 2019 20:14
Show Gist options
  • Save necccc/6810983cd90817fbd611be75c341cec9 to your computer and use it in GitHub Desktop.
Save necccc/6810983cd90817fbd611be75c341cec9 to your computer and use it in GitHub Desktop.
Gist for "Next.js & Apollo GraphQL Performance Tuning: From Lists to Details"
import { compose, graphql } from 'react-apollo'
// requesting the same fields as they were in the list
// specific to the ID we want to see in details
export const getStarshipQuick = gql`
query getStarshipQuick($id: ID) {
Starship(id: $id) {
items {
id
name
}
}
}
`
// requesting the full data from graphql, by the ID
export const getStarshipFull = gql`
query getStarshipFull($id: ID) {
Starship(id: $id) {
items {
id
name
model
length
crew
manufacturer
}
}
}
`
class Starship extends React.Component {
render() {
const { starship } = this.props.data
return (<div>
<h1>{starship.name}</h1>
<img src="{starship.picture}" />
<ul>
<li>Model: {starship.model}</li>
<li>Length: {starship.length}</li>
<li>Crew: {starship.crew}</li>
<li>Manufacturer: {starship.manufacturer}</li>
</ul>
</div>)
}
}
// the getInitialProps of nextjs prepares the Starship ID for us
// grabbing it from the query
Detail.getInitialProps = async function ({ query }) {
return {
id: query.id
}
}
// we set up two things here:
// - get notified if the GraphQL Query is in loading state
// - put the ID from the props, to the variables, so the Query receives it
const queryParams = {
options: props => {
return {
notifyOnNetworkStatusChange: true,
variables: {
id: props.id
},
}
}
}
// here we compose two GraphQL queries together
// they will run in order as we compose them
// first the Quick one - which will be redirected to the cache, and render instantly
// then the Full one - after resolving that one from the network,
// it will render the rest of the details
export default compose(
graphql(getStarshipQuick, queryParams),
graphql(getStarshipFull, queryParams)
)(Detail)
import { graphql } from 'react-apollo'
// requesting the data from graphql, by the ID
export const getStarship = gql`
query getStarship($id: ID) {
Starship(id: $id) {
items {
id
name
model
length
crew
manufacturer
}
}
}
`
class Starship extends React.Component {
render() {
const { starship } = this.props.data
return (<div>
<h1>{starship.name}</h1>
<img src="{starship.picture}" />
<ul>
<li>Model: {starship.model}</li>
<li>Length: {starship.length}</li>
<li>Crew: {starship.crew}</li>
<li>Manufacturer: {starship.manufacturer}</li>
</ul>
</div>)
}
}
// the getInitialProps of nextjs prepares the Starship ID for us
// grabbing it from the query
Detail.getInitialProps = async function ({ query }) {
return {
id: query.id
}
}
// we set up two things here:
// - get notified if the GraphQL Query is in loading state
// - put the ID from the props, to the variables, so the Query receives it
const queryParams = {
options: props => {
return {
notifyOnNetworkStatusChange: true,
variables: {
id: props.id
},
}
}
}
// compose the component and the GraphQL Query together
// using the `graphql` method from react-apollo.
export default graphql(getStarship, queryParams)(Detail)
// our GraphQL Query,
// get the name and ID of some Starships
export const getStarships = gql`
query getStarships {
starshipList {
items {
name
id
}
}
}
`
// a small component to list the data above
const List = (props) => (<div>
<ul>
{
// data structure here matches the data structure in the query
// using next/link, we're pointing these list items to the starship detail pages
props.data.starshipList.items.map(item => (<li key={item.id}>
<Link href={{ pathname: '/starship', query: { id: item.id } }}>
<a>{item.name}</a>
</Link>
</li>))
}
</ul>
</div>)
// compose the component and the GraphQL Query together
// using the `graphql` method from react-apollo.
export default graphql(getStarships)(List)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment