Bryan Stearns
Bryan Stearns

Reputation: 1337

Apollo graphql-connected React component isn't rerendering

I'm working on building an authentication mechanism over graphql, and I'm trying to figure out why a graphql-connected component isn't rerendering after relogin... for example:

I can see that the graphql request succeeds (and have watched in Chrome's debugger as the APOLLO_QUERY_RESULT action is handled by react-apollo's reducer and updates the state in the store).

I've tried to find where React is checking to see if the component's props have changed, but I'm enough of a React debugging noob that I haven't figured out where to find that code in the web inspector: maybe something I don't understand about how React is packaged for distribution.

I clear out the ApolloClient's store (by calling resetStore()) on both login and logout, since I don't want to accidentally reuse data from the other authenticatedness; however, removing these calls doesn't get rid of the problem. Interestingly (?), if I force the connection to bypass the cache by providing { options: { fetchPolicy: 'network-only' } } in the graphql() call, the problem goes away. (Not a viable solution - I'd like to benefit from the cache generally.)

I've built a stripped-down example: https://github.com/bryanstearns/apollo-auth-experiment and you can see it in a CodeSandbox: https://codesandbox.io/s/m4nlpp86j (you'll probably want to access the running example from an independent browser window at https://m4nlpp86j.codesandbox.io/ because the sandbox editor kinda makes the web debug extensions act weird).

Upvotes: 3

Views: 739

Answers (1)

Daniel Rearden
Daniel Rearden

Reputation: 84657

To fix this behavior, modify your graphql HOC to include notifyOnNetworkStatusChange in the options.

export const Users = graphql(usersQuery, { options: { notifyOnNetworkStatusChange: true } })(RawUsers);

I don't think you should have to do that -- I think data.loading is supposed to accurately reflect the status of your query regardless of that option being set to true, unlike data.networkStatus but it looks like it's a known bug.

As far as resetStore -- it doesn't actually wipe your entire store, but rather wipes away your store and refetches all your active queries. If you wanted to blow away your store, since you're already integrating Redux with Apollo, the easiest thing to do would be to create an action to do that.

You may also want to consider a session-based authentication mechanism, rather than relying on the client to persist a token. It's pretty simple to implement server-side, would not only involve less work on the client-side (don't have to remember to pass the token in with every request), and would let you keep your user logged in after they navigate away from the page.

Upvotes: 3

Related Questions