apollo-client icon indicating copy to clipboard operation
apollo-client copied to clipboard

Loading stuck always true after sending request when using useMutation hook 🤔

Open igdev116 opened this issue 2 years ago • 36 comments

I'm using custom useMutation hook but loading state is always true and data is always undefined

const [createPost, { loading, data }] = useCreatePostMutation(); // same `const { loading, data, mutate: createPost } = useMutation;`

console.log(loading); // always true after sending request
console.log(data); // undefined

const handleCreatePostSubmit = async () => {
  const response = await createPost({
    variables: {
      createPostInput: {
        caption,
        base64Photo: preview,
      },
    },
  });
};

System: OS: Windows 10 10.0.19043

Binaries: Node: 14.18.1 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.17 - ~\AppData\Roaming\npm\yarn.CMD npm: 6.14.15 - C:\Program Files\nodejs\npm.CMD

Browsers: Edge: Spartan (44.19041.1266.0), Chromium (100.0.1185.39)

npmPackages: @apollo/client: ^3.5.10 => 3.5.10 apollo-server-micro: ^3.6.7 => 3.6.7

igdev116 avatar Apr 16 '22 08:04 igdev116

I just created a useLoading hook to make the request but it seems to be quite inconvenient 🙄

const useLoading = () => {
  const [loading, setLoading] = useState(false);

  const handleAction = async <T>(action: () => Promise<T>) => {
    setLoading(true);

    try {
      return await action();
    } finally {
      setLoading(false);
    }
  };

  return [loading, handleAction] as const;
};

Use it

const [loading, handleAction] = useLoading();

const handleCreatePostSubmit = async () => {
  const response = await handleAction(() =>
    createPost({
      variables: {
        createPostInput: {
          caption,
          base64Photo: preview,
        },
      },
    }),
  );
};

igdev116 avatar Apr 16 '22 09:04 igdev116

Same is my issue here, I am using

const [signIn, { loading, error, data }] = useMutation(
    gql`
      mutation SIGNIN($input: SignInInput!) {
        signIn(input: $input) {
          token
        }
      }
    `,
    { errorPolicy: "all" }
);

On calling the signIn function, the loading state gets set to true, the request gets sent and a correct response is received (according to the chrome dev tools network tab) from the server but the loading (stuck at true) and data(stuck at undefined) states never change.

This is my apollo client

export const client = new ApolloClient({
  uri: process.env.NEXT_PUBLIC_GQL_ENDPOINT,
  cache: new InMemoryCache({ addTypename: false }),
});

Library versions are

"@apollo/client": "^3.5.10",
"graphql": "^16.3.0",
"next": "12.1.5",
"react": "18.0.0",

green-mint avatar Apr 16 '22 22:04 green-mint

@green-mint Did you fix it yet? 😄

igdev116 avatar Apr 17 '22 06:04 igdev116

@riddle-tran it works perfectly, thanks a lot

igdev116 avatar Apr 17 '22 15:04 igdev116

I found a workaround for this problem if you want to use React 18

const [error, setError] = useState(null)
const [loading, setLoading] = useState(false)
const [data, setData] = useState(null)
const [mutateFunction] = useMutation(
  GRAPHQL_QUERY
  {
    onError: (error) => {setError(error)},
    onCompleted: (data) => {
      setData(data)
      setLoading(false)
    }
  }
)

function mutateFinally() {
  setLoading(true)
  mutateFunction()
}

mutateFinally()

henriquekirchheck avatar Apr 19 '22 13:04 henriquekirchheck

Investigating this issue came across this issue in react's github https://github.com/reactjs/reactjs.org/issues/4534#issuecomment-1085358976

Tried it by myself by setting StrictMode off and this issue didn't happen anymore. We also had an issue where readFragment and readQuery do not trigger re-renders when the cache gets updated. And it was also fixed by turning off React's strict mode.

nicolasepiscopo avatar Apr 19 '22 15:04 nicolasepiscopo

Same issue on React 18, works on React 17 😅

Maxou44 avatar Apr 19 '22 20:04 Maxou44

Same issue on React 18, no answer yet?

hshoja avatar Apr 20 '22 13:04 hshoja

I have same issue on React 18 haha... custom hook the only solution for today until the apollo-client commit bug fixes

syukronarie avatar Apr 21 '22 01:04 syukronarie

Experiencing the same issues with:

"@apollo/client": "^3.5.10",
"graphql": "^16.3.0",
"next": "12.1.5",
"react": "18.0.0",
"react-dom": "18.0.0"

Setting reactStrictMode to false made no difference :(

https://github.com/apollographql/apollo-client/issues/9602#issuecomment-1102677886 is simple and effective workaround though 🙂

Manoj-nathwani avatar Apr 21 '22 21:04 Manoj-nathwani

I'm experiencing same problem. My setup (CRA)

    "@apollo/client": "^3.5.10",
    "graphql": "^16.3.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "react-scripts": "5.0.1",

Removing React.StrictMode works though

juancarlosqr avatar Apr 23 '22 16:04 juancarlosqr

@juancarlosqr Downgrade react 18.0.0 to 17.0.2 and it will work perfectly 🎉🎉🎉

igdev116 avatar Apr 24 '22 05:04 igdev116

@igdev116 thanks, I can try that out but a fix here is still needed I guess. Were you able to identify what's the underlying issue? Most likely related to StrictMode as pointed in the issue from @nicolasepiscopo

juancarlosqr avatar Apr 25 '22 10:04 juancarlosqr

Looks like this is probably a duplicate of #9560.

rpendleton avatar Apr 25 '22 19:04 rpendleton

Same issue here. Works fine when strictmode is deactivated. React 17.0.2 and "@apollo/client": "^3.6.0".

brampurnot avatar Apr 27 '22 09:04 brampurnot

This is also impacting the loading state of lazyQueries. With [email protected] and @apollo/[email protected], removing React.StrictMode also fixes the issue.

CowDotDev avatar Apr 27 '22 14:04 CowDotDev

This is happening for me in React Native with @apollo/client >= 3.6.0 without strict mode. ([email protected], [email protected], StrictMode is not set). Both lazy and non-lazy queries are hanging. Some of the lazy queries are actually returning data but loading is still true, and some non-lazy ones are just never even returning data. v3.5.10 still works perfectly, so it's definitely something that changed in 3.6.0.

simon-abbott avatar May 03 '22 16:05 simon-abbott

@igdev116 (and others) Could anyone put together a quick reproduction, so I can test a potential solution I have in mind?

benjamn avatar May 05 '22 20:05 benjamn

Just to add another diagnostic to the mix, I would encourage everyone to try running npm i @apollo/client@next (to get version 3.6.3). I doubt everyone's issues will be fully addressed by this version, but I know we've improved React loading states in this release.

benjamn avatar May 05 '22 22:05 benjamn

Strict mode on: same results, loading stuck to true after completing a mutation Strict mode off: fixes it @apollo/client: '3.6.2': fixes it

Thanks @benjamn!

Forfold avatar May 10 '22 19:05 Forfold

For me this happens as soon as I upgrade to 3.6.0. Works fine with 3.5.10, so yes something must have changed in 3.6.0+.

Here's what I'm using:

"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",

@benjamn I tried it on @apollo/client@next, but same problem for me. For now I'll stick to 3.5.10. 😃

amerikan avatar May 11 '22 06:05 amerikan

@benjamn 3.6.3 didn't fix it for me, but it seems that 3.6.4 did!

simon-abbott avatar May 17 '22 21:05 simon-abbott

Was facing the exact same problem with react ^18.1.0 and @apollo/client 3.5.10, React strict mode off solved it !

ChoucheneHayfa avatar May 26 '22 13:05 ChoucheneHayfa

@apollo/[email protected] fixes it for me with React 18

busbyk avatar Sep 16 '22 15:09 busbyk

having the same issue with next.js React 18, setting reactStrictMode = false works fine.

jruizvisp avatar Oct 09 '22 12:10 jruizvisp

having the same issue with next.js React 18, setting reactStrictMode = false works fine.

Same here!

sebasegura97 avatar Nov 15 '22 11:11 sebasegura97

Is there any work around aside from disabling the strict mode?

davidkhierl avatar Dec 11 '22 15:12 davidkhierl

Hey guys, it looks like this is still an issue, trying React 18 with React Native and Apollo client 3.7.3 and facing the same issue , are you all using the custom hook to fix this ?

andrea-oo avatar Jan 03 '23 12:01 andrea-oo

Hey guys in case you still have this issue with latest versions @apollo/client: ^3.7.3, react: ^18.2.0 and react-native: ^0.70.6, for me it was enough to stick an await in front of the mutate function to make it asynchronous to fix the issue

andrea-oo avatar Jan 04 '23 15:01 andrea-oo

Hi, below option works for me when call the mutation: callMutation({variables: {...}, notifyOnNetworkStatusChange: true }) With notifyOnNetworkStatusChange seems like the loading state will be refresh after component rendered.

hon-tnguyen6 avatar Oct 24 '23 04:10 hon-tnguyen6

I'm sorry that this still seems to be happening for some of you.

Could someone please take the time and put together a reproduction?

If we can't see the problems ourselves (and we don't!), we can't fix it 😞

phryneas avatar Oct 24 '23 09:10 phryneas