2

I have a mutation which I use to login on my application. I want to rerun that login mutation every 5 minutes to check for updates to their profile. useQuery has a pollingInterval options but useMutation does not.

I tried using a hook to run the mutation on an interval but that doesn't really work because the useAuth hook is used in multiple components at the same time so it ends up creating an interval for each component.

function useInterval(callback: () => any, delay: number | null) {
  const savedCallback = useRef<any>();
  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);
  useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      const id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
}


function useAuth(){
  const [login,{data:loginData} = useMutation(gql`
   ...
  `);

  useInterval(() => login(Cookies.get(TOKEN_NAME),1000*60*5);

  return login;
}

function App(){
 const login = useAuth();
 useEffect(() => {
   login(Cookies.get(TOKEN_NAME));
 },[login]);

 ...
}

1 Answer 1

2

What you want to do is create a context with a Provider that sits high up in your react component tree. Here is the documentation, context docs.

First you need to create the provider, probably in the same location you create the useAuth hook.

import React, {useContext, createContext} from 'react';

const AuthContext = createContext();

function AuthProvider({ children }) {
  const [login,{data:loginData} = useMutation(gql`
   ...
  `);

  useInterval(() => login(Cookies.get(TOKEN_NAME),1000*60*5);

  return (
    <AuthContext.Provider value={login}>{children}</AuthContext.Provider>
  )
}

function useAuth(){
  const context = useContext(AuthContext);
  return context;
}

Then change the App definition like so,

function App() {
  return (
    ...
    <AuthProvider>
      ...
    </AuthProvider>
    ...
  );
}

By placing it in a provider (that is high in the tree), the useEffect will likely only run on app load and when the useInterval triggers. If the code is just in a functional hook, it can change frequently (component mount/unmount, prop changes, etc).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.