I made React custom hook with react-query but had problem with using it in components
this is custom hook, @param : code @return : id Token
export const useGetIdToken = (code: string | null) => {
const logintype = "kakao";
const { isLoading, data, error } = useQuery({
queryKey: ["idToken"],
queryFn: async () => {
const res = await axiosInstance.get(
`/v1/auth/${logintype}/idtoken?code=${code}`,
);
return res.data;
},
});
return {
idToken: data || null,
isLoading,
error,
};
};
and using in component like this
const KakaoLogin = () => {
//path에서 query string 받아오기
const [searchParams, setSearchParams] = useSearchParams();
const code = searchParams.get("code");
//code 백으로 보내고 idToken 받아오기
const fetchData = useGetIdToken(code);
const idToken = fetchData.idToken;
useEffect(() => {
console.log(idToken);
}, [idToken]);
// useEffect(() => {
// console.log(code);
// const fetchData = useGetIdToken(code);
// console.log(fetchData.idToken);
// }, [code]);
return <div>Loading...</div>;
};
this works but if i'm using it in useEffect() like comment i got errors 'Invalid hook call' but i want to make this custom hook work only when variable 'code' is changed is any other way i can use it in useEffect?
i made function using custom hook, and call it in useEffect but it stays in same errors. then i just give up using useEffect and put hook at the top then it works successfully but i'm still curious about why these error came out and any other way to fix it
first error comments are following
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
at Object.throwInvalidHookError (react-dom.development.js:16227:1)
at Object.useContext (react.development.js:1618:1)
at useQueryClient (QueryClientProvider.tsx:11:1)
at useBaseQuery (useBaseQuery.ts:42:1)
at useQuery (useQuery.ts:46:1)
at useGetIdToken (useGetIdToken.tsx:13:1)
at kakaoLogin.tsx:23:1
at commitHookEffectListMount (react-dom.development.js:23150:1)
at commitPassiveMountOnFiber (react-dom.development.js:24926:1)
at commitPassiveMountEffects_complete (react-dom.development.js:24891:1)
install BrowserRotuer, make functions with hooks and call it in useEffect but never works i hope i can get why custom hook can't be used in useEffect, and any other option i can use it when this first renders
I will break this into two parts:
code
"Invalid hook call"
The "Invalid hook call" is a very common issue when working with React and occurs when you don't follow the rules of React hooks.
The error itself is very descriptive of what the issue is and where you can read more about it but let's debunk it here:
React hooks, including custom hooks like your
useGetIdToken
, must adhere to the Rules of Hooks. These rules include:useEffect
as with your example.In your case the error occurs when you try to use the custom hook inside the
useEffect
hook. This is a violation of the first rule, asuseEffect
can be considered a nested function within your component.To resolve this, you should call your custom hook at the top level of your component, just like you did in your working example.
How to make a React Query Query listen for changes
You can use your criteria as a query key. The query is dependable on the data (
code
) and when the data is a part of the query key, the query will update any time the data (code
in your case) updates.The query keys act as a dependency of the query. Whenever a query key changes, the query will automatically update.
You can read about it in the TanStack documentation about Query Keys.
TLDR; Using any types of hooks in
useEffect
goes against the React Rules of Hooks.There is always another way to work with hooks that does not include using the hook itself inuseEffect
. You can see the code above to learn how to make your React Query query listen for changes without using it directly in auseEffect
hook.