apollo-client: Warning: Can't perform a React state update on an unmounted component.

This is the code for useMuation

  const [tokenAuthCall, { loading: mutationLoading, error: mutationError }] = useMutation(LOGIN_MUTATION, {
    refetchQueries: [ { query: ME_QUERY }], awaitRefetchQueries: true,
  })

But on using refetchQueries it gives the following warning

Warning: Can’t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

This is my nav code:

function NavContents(props) {
  let me
  let data = MeQuery()
  try {
    me = data.me
  } catch {
    me = false
  }
return (
    <React.Fragment>
{me && (
              <li className="nav-item">
                <NavLink to="/profile" className="nav-link">
                  {me.name}
                </NavLink>
              </li>
            )}
            {me && (
              <li className="nav-item">
                <NavLink to="/signout" className="nav-link">
                  (SignOut)
                </NavLink>
              </li>
            )}
<React.Fragment>
)

And the is MeQuery()

import React, { Component } from "react"
import { gql, useQuery } from "@apollo/client"

const ME_QUERY = gql`
  query {
    me {
      email
      name
    }
  }
`

function MeQuery() {
  const { loading, error, data } = useQuery(ME_QUERY)
  let value
  if (loading) return "Loading..."
  if (error) {
    value = false
  }
  value = data
  return value
}

export default MeQuery
export {ME_QUERY}

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 50
  • Comments: 50 (5 by maintainers)

Commits related to this issue

Most upvoted comments

Happened also when route changes while current route has a useQuery

Still actual!!

I was struggling with a similar issue an solved it by using useLazyQuery on mount instead of useQuery on each render, as inspired by jordicasesnoves:

import { useEffect } from "react";
import { useLazyQuery } from "@apollo/client";

  // ...
  const [myQueryExecutor, { data }] = useLazyQuery(MY_QUERY);

  // execute query on component mount
  useEffect(
    () => { myQueryExecutor(); },
    [myQueryExecutor]
  );

I got the same issue as well with @apollo/client version 3.1.1 on route change when the current route is using useQuery.

Still the same warnings 😦

is there any updates on this error message?

This should be fixed with @apollo/client >= 3.4 - thanks!

still failing.

I got the same issue when the route changes with “@apollo/react-hooks”: “^3.1.5”

Is there any update regarding this? Still the same warning when using useQuery and changing route. And it seems to me that using useLazyQuery and useEffect is a workaround, not an actual solution?

Same here

@Felix-Indoing same for me 😕

I found the cause. The issue is because of <React.StrictMode> https://github.com/apollographql/react-apollo/issues/3635

same here

@jgwiazdowski The best workaround so far (in my opinion) is to use a hook telling you whether a component is mounted or not and to pass that Boolean to the skip parameter of your query. It is a bit cleaner than useLazyQuery.

it’s still an issue

so only solution now is lazy query and useEffect?

@suhanw do you have your <RouterProvider> outside your <ApolloProvider> in your component hierarchy? Does reversing them make a difference?

In case it helps anybody, I was getting the same error on all my useQuery hooks after any route change in NextJS, and the problem ended up being unrelated to useQuery itself. Instead, it was simply the fact that I was setting a reactive variable within a component render without wrapping it in a useEffect hook. Which was breaking React’s state reconciliation and eventually leading to the error discussed above. In short, if you’re seeing the above error coupled with “Cannot update a component (…) while rendering a different component (…)”, check out this post and search your codebase for all the places where you set the values for your reactive variables.

same here

Still happening for me with useQuery on 3.0.0-rc.2

Edit: Oh well, just saw https://github.com/apollographql/apollo-client/pull/6395#issue-428502047 that talks about #6216’s revert

i have encountered same problem. I tried every possibility. This is the solution that help me with. Using skip { skip:true } after getting data solves

const [skip, setSkip] = useState(false)
const [securities, isLoading] = useQueryGetMinifiedSecurities(skip)
const [datasource, setDatasource] = useState([])

 useEffect(() => {
    if (securities && !isLoading) {
      setDatasource(securities)
      setSkip(true)
    }
  }, [isLoading, securities])

useLazyQuery and useEffect does not work for me sadly.

Any movement on this?

Maybe this is helpful for someone out there… (⚠️ I am a Java guy, just doing some React + GraphQL and no experience in this at all, so apologies in case this looks awful)

This is how I solved it:

  const {loading, error, data, stopPolling, startPolling} = useQuery(MY_QUERY,
    {fetchPolicy: "network-only"});

  React.useEffect(() => {
    startPolling(pollingIntervalMillis);
    return () => {
      stopPolling();
    };
  });

After doing this, I do not see the warning anymore.

I’m getting this warning when I call the refetch function returned by useQuery(). When I comment out my invocation of refetch() the error goes away. I’m using @apollo/client@3.3.7 and react-native@0.63.4.

UPDATE: In my case, I was getting this error in my Jest tests. I realized that MockedProvider was returning this error No more mocked responses for the query for my refetch() call. Once I added another response to my mocks array, the original warning went away.

So I still think that the warning was caused by using refetch because I only saw that warning when I used it (other cases where I didn’t have enough mocked responses did not cause this warning message to appear). Even though the warning was the result of something that I was doing wrong, the message was completely unhelpful and misleading. The warning suggests that I need to add a useEffect cleanup, but that wasn’t the correct solution in my case.

Every time I get “state update on an unmounted component” in the console, this issue makes it hard to tell if it is really due to state in my code or not and if I have actually fixed legitimate issues because this issue causes so many errors. If there is a way to fix this without breaking SSR, it would really help.

This issue is related to StrictMode, and I have a working reproduction on https://github.com/apollographql/apollo-client/issues/8011

I also tried wrapping ApolloProvider inside BrowserRouter in index.ts (before I had BrowserRouter wrapping my routes in App.js) and I am still getting the error:

` ReactDOM.render(
<Router>

  <ApolloProvider client={client}>

    <React.StrictMode>

      <App />

    </React.StrictMode>

  </ApolloProvider>

</Router>,

document.getElementById('root')

); `

I have also tried swapping Router and ApolloProvider in the code above and I still get the warning.

I can confirm though that using useLazyQuery + useEffect gets rid of the warning. Not sure if this is intended or ideal.

Still getting this issue on 3.4.0-beta.11 Even with @DylanVann 's fix above.

Screenshot 2021-02-20 at 20 21 02

I’m still seeing this error when using useQuery with a basic query and the follow params:

{
  fetchPolicy: "no-cache",
  errorPolicy: "all"
}

My useEffect dependency array includes the data, loading, and error vars returned from useQuery, if that makes a difference.

I’m using StrictMode and on "@apollo/client": "3.0.0-rc.5".

Happy to provide more details if needed!