Search code examples
react-nativereact-navigationapollo-client

How to logout the user on apollo-link-error in react-native app?


To navigate around in my react-native app, I am using "react-navigation".

With the code below, I can successfully intercept all necessary errors that are coming from the server.

const linkError = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    // Logout user
    // 1. Issue logout mutation
    // 2. Navigate to Login screen
    graphQLErrors.map(({ message, locations, path }) =>
      console.log(
        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
      )
    );
  }
  if (networkError) console.log(`[Network error]: ${networkError}`);
});

const client = new ApolloClient({
  link: ApolloLink.from([linkError, stateLink, authLink, httpLink]),
  cache,
});

The question is how to navigate the user to "Login" screen and issue "Logout" mutation if an error happens?


Solution

  • You could rewrite your code to have client returned from a hook. It could be similar to this:

    export const useApolloClient = () => {
      // Assuming `logout` is a function that removes the user token
      const { logout } = useAuth();
    
      return useMemo(() => {
        const linkError = onError(({ graphQLErrors, networkError }) => {
          if (graphQLErrors) {
            graphQLErrors.map(({ message, locations, path }) => {
              if (message === 'Unauthorized') {
                // Or whatever may be the reason for logging out
                logout()
              }
    
              console.log(
                `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
              )
            });
          }
          if (networkError) console.log(`[Network error]: ${networkError}`);
        });
    
        return new ApolloClient({
          link: ApolloLink.from([linkError, stateLink, authLink, httpLink]),
          cache,
        });
      }, [logout]);
    };
    

    A couple of comments on your comments:

    // Logout user // 1. Issue logout mutation

    Not sure what you mean by logout mutation - I suppose you store a token that represents a signed-in user.

    // 2. Navigate to Login screen

    If you use react-navigation, I don't think that manual navigation would be a good practice. According to their documentation, you should simply return the navigator presenting Login screen based on isSignedIn. I would suggest using a JWT token (if that's the supposed flow) as a isSignedIn flag.