graphqlapollo-clientgraphcool

Logged in state doesn't reactively update in React, Apollo Client 2, Graphcool


Im using React, Apollo Client 2 and Graphcool. Ive implemented a login form. On the login page either a login form or a logout button are shown depending on weather the client is logged in.

My code works but does not update reactively. After a user logs in or out nothing changes until they refresh the page. How can I make my code reactive?

import React from 'react';
import { graphql, compose } from 'react-apollo';
import gql from 'graphql-tag';

class Login extends React.Component {
    constructor(props) {
        super(props);
        this._confirm = this._confirm.bind(this);
    }

    _confirm = async e => {
        e.preventDefault();

        const result = await this.props.LoginMutation({
            variables: {
                email: '5@gmail.com',
                password: 'password',
            },
        });

        const token = result.data.authenticateUser.token;
        this._saveUserData(token);
    };

    _saveUserData = token => {
        localStorage.setItem('auth-token', token);
    };

    render() {
        return (
            <div>
                {this.props.LoginQuery.user ? (
                    <button onClick={() => localStorage.removeItem('auth-token')}>
                        Logout
                    </button>
                ) : (
                    <form onSubmit={this._confirm}>
                        <input type="email" id="email" />
                        <input type="password" id="password" />
                        <button type="submit">Login</button>
                    </form>
                )}
            </div>
        );
    }
}

const LoginMutation = gql`
    mutation authenticateUser($email: String!, $password: String!) {
        authenticateUser(email: $email, password: $password) {
            token
        }
    }
`;

const LoginQuery = gql`
    query AppQuery {
        user {
            id
        }
    }
`;

const LoginContainer = compose(
    graphql(LoginMutation, { name: 'LoginMutation' }),
    graphql(LoginQuery, { name: 'LoginQuery' }),
)(Login);

export default LoginContainer;

Solution

  • Anything that concerns UI, doesn't necessarily need to be protected. Therefore you can easily just use state or a data store (such as redux, mobx etc.) to triggers updates to the UI.

    If you want reactive updates to your UI based off of your mutations with GraphQL. I would honestly recommend implementing Subscriptions which will give you the sort of reactive data flow that you're looking for.

    Subscriptions ~ Apollo Client