Hi everyone 👋
React-Apollo is the go to library to use graphQL alongside React. Their documentation is really cool and comprehensive, but they promote the usage of React Hooks to perform all your requests.
Regarding your frontend architecture, you may not be thrill by the idea of letting all your React components handling these kind of responsibility.
In my case, we were integrating GraphQL within an existing frontend app with React, React-redux and redux-thunk. The code is written the way that all network API calls are executed via redux actions (using redux thunk).
Assuming you have knowledge of redux-thunk and React-Apollo, I will show some basic example of actions.
For these examples, I will use a public GraphQL API :
import ApolloClient from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink } from "apollo-link-http";
import { setContext } from "apollo-link-context";
import * as UserUtils from "../utils/user";
const cache = new InMemoryCache();
const link = new HttpLink({
uri: `https://directions-graphql.herokuapp.com/graphql`
});
const authLink = setContext((_, { headers }) => {
const token = UserUtils.getTokenFromLocalStorage();
return {
headers: {
...headers,
authorization: token
}
};
});
const client = new ApolloClient({
cache,
link: authLink.concat(link)
});
export default client;
import gql from 'graphql-tag';
import graphQlClient from "client"
export const signUp = (username = "johndoe", email = "john.doe@test.com", password = "mypassword") => (dispatch, getState) => {
dispatch(setLoading(true))
graphQlClient
.mutate({
mutation: gql`
mutation($username: String!, $email: String!, $password: String!) {
signUp(username: $username, email: $email, password: $password) {
user {
id,
username,
email
}
}
}
`,
variables: { username, email, password },
update: (_cache, result) => {
const { data: { signUp: { user: { username, email } } } } = result
dispatch(signIn(email, password))
},
})
.catch((error) => {
console.log('error', error)
})
.finally(() => {
dispatch(setLoading(false))
})
}
const setTokenToLocalStorage = (token) => {
localStorage.setItem('token', token)
}
const getTokenFromLocalStorage = () =>
localStorage.getItem("token") || null;
export const signIn = (email, password) => (dispatch, getState) => {
dispatch(setLoading(true))
graphQlClient
.mutate({
mutation: gql`
mutation($email: String!, $password: String!) {
signIn(userIdentifier: $email, password: $password") {
token
}
}
`,
variables: { email, password },
update: (_cache, result) => {
const { data: { signIn: { token} }} = result
dispatch(setTokenToLocalStorage(token))
},
})
.catch((error) => {
console.log('error', error)
})
.finally(() => {
dispatch(setLoading(false))
})
}
export const direction = (coordinates = {startLat: 50.6333, startLng: 3.0667, endLat: 48.8534, endLng: 2.3488} , travelMode = "driving" ) => (dispatch, getState) => {
dispatch(setLoading(true))
graphQlClient.
graphQlClient.query({
query: gql`
input PlaceCoordinatesInput {
startLat: Float!
startLng: Float!
endLat: Float!
endLng: Float
}
enum AllowTravelModes {
transit
driving
walking
}
query($coordinates: PlaceCoordinatesInput!, $travelMode: AllowTravelModes!) {
direction(coordinates: $coordinates, travelMode: $travelMode) {
steps {
stepInstruction
}
}
}
`,
variables: { coordinates , travelMode },
}).then((result) => {
const { data: { direction } } = result
dispatch(doSomethingWithDirection(direction))
})
.catch((error) => {
console.log('error', error)
})
.finally(() => {
dispatch(setLoading(false))
})
}
For the sake of the example I used default values for the actions parameters.
As you can see, you easily manipulate graphql apollo client inside redux thunks actions.
To conclude, I will share you some links to help you during your journey of learning GraphQL and react-apollo as well as the repository containing the source code of these examples.
Documentation :
Further reads :
- https://learn.hasura.io/graphql/react
- https://stackoverflow.com/questions/43471623/apollo-client-mutation-error-handling
Source code :
Top comments (0)