skip to Main Content

my hook:

export function useToken2() {
  const { data: session, status } = useSession();
  const [token, setToken] = useState<string | null>(null);

  useEffect(() => {
    if (status === 'authenticated' && session?.accessToken) {
      logger('useEffect setToken')
      setToken(session.accessToken);

    }
  }, [status, session]);

  const tokenFn = useCallback(async (): Promise<string> => {
    return new Promise<string>((resolve) => {
      if (token != null) {
        resolve(token);
      } else {
        const tokenInterval = setInterval(() => {
          if (token != null) {
            clearInterval(tokenInterval);
            resolve(token);
          }
        }, 100);
        setTimeout(() => {
          clearInterval(tokenInterval);
          logger('tokenFn timeout')
          resolve('');
        }, 5000);
      }
    });
  }, [token]);

  return {
    tokenFn,
  };
}

hook call:

const Test: FC = () => {
  const [token, setToken] = useState('');
  const {tokenFn} = useToken2()

  useEffect(() => {
    tokenFn().then((res) => {
      setToken(res)
    })
  }, []);

  return (
      <>
        {token}
      </>
  );
};

The token is always empty, but hook cannot return null as token.
status === ‘authenticated’ is set some time after start.
How to expect token setting in tokenFn? setInterval doesn’t work.
Log:

  • useEffect setToken
  • tokenFn timeout

2

Answers


  1. Chosen as BEST ANSWER

    solved

    import {useSession} from 'next-auth/react';
    import {useQuery} from "react-query";
    
    export function useToken2() {
      const { data: session, status } = useSession();
      const { data: token } = useQuery(["token"], async () =>
      { return  session?.accessToken ?? ""}, {enabled: !!session?.accessToken && status === "authenticated"});
      
      return {
       token
      };
    }
    

  2. In your code, it seems that you are not updating the token state in the useEffect inside the useToken2 hook. The condition if (token != null) inside the tokenFn callback does not update the state.

    To fix this issue, you can update the token state whenever it changes using the setToken function inside the useEffect of the useToken2 hook. Here’s an updated version of your

    Here is an updated code:

    export function useToken2() {
      const { data: session, status } = useSession();
      const [token, setToken] = useState<string | null>(null);
    
      useEffect(() => {
        if (status === 'authenticated' && session?.accessToken) {
          setToken(session.accessToken);
        }
      }, [status, session]);
    
      const tokenFn = useCallback(async (): Promise<string> => {
        return new Promise<string>((resolve) => {
          if (token != null) {
            resolve(token);
          } else {
            const tokenInterval = setInterval(() => {
              if (token != null) {
                clearInterval(tokenInterval);
                resolve(token);
              }
            }, 100); // Check every 100 milliseconds for token availability
          }
        });
      }, [token]);
    
      return {
        tokenFn,
      };
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search