Problem with maximum update depth exceeded with token for fetcher #654
-
Hello guys, my first time posting here. 👋 I'm using this awesome library and it's working really well, thanks! Now I'm having a problem with a maximum update depth exceeded while trying to reuse the hook in another component. Until now, the same calls are working pretty fine and no errors, but as I tried to use the same hooks in another screen it started the problem. So, what I have here are the following: This hook: export function useEvents(userToken, date) {
const { data, error } = useSWR(['/calendar/events', userToken, date], fetch);
return {
events: data,
isLoading: !error && !data,
isError: error,
};
} this fetcher: export function fetch(path, userToken, date) {
return API.get(path, {
params: {
from: Array.isArray(date) ? date[0] : date,
to: Array.isArray(date) ? date[1] : date,
},
headers: {
Authorization: `Bearer ${userToken}`,
},
}).then((data) => data);
} (I'm using axios here and an interceptor that when it resolves it already returns response.data) I'm calling it like: const {
events,
isLoading: isEventsLoading,
isError: isEventsError,
} = useEvents(userToken, selectedCalendarDay); and the token comes from Redux User State: const userToken = useSelector((state) => state.user.auth.userToken); I have in the same component more two other hooks, that are similar to this one, but different endpoints but using also token, just to let you guys know, if it affects in some way. But as I said, it works really well for another route (component / screen) of the app but as I tried to use in another place (more specifically in the home screen of the app, after user logins) it started throwing the maximum update error. And this is the part in my useEffect(() => {
function tryLoginWithStorage() {
const storedToken = window.localStorage.getItem('token');
if (storedToken) {
loginWithToken(storedToken) // here as a API get using the token to get the user data
.then((userData) => {
dispatch(login({ token: storedToken, user: { ...userData } }));
})
.catch((error) => {
if (error.status === 401) {
dispatch(
setShowDialog({
show: true,
content:
'Sorry, invalid token, please re-login.',
})
);
window.localStorage.removeItem('token');
} else {
dispatch(
setShowDialog({
show: true,
content:
'Unknown error, please contact support.',
})
);
console.error('Error on API', error);
}
})
.finally(() => {
dispatch(setAppLoading('idle'));
setTimeout(() => {
history.replace('/'); // here it will render the HomeScreen (inside a PrivateRoute) where I use the hook with the token
}, 500);
});
} else {
dispatch(setAppLoading('idle'));
if (
history.location.pathname !== '/' ||
history.location.pathname !== '/login'
)
history.replace('/');
}
}
tryLoginWithStorage();
initServices();
}, [dispatch, history]); Appreciate the help, I'm really in trouble and can't find how to make this work. I've commented the const { data, error } = useSWR(userToken ? ['/calendar/events', userToken, date] : null, fetch); but it didn't work too. 😢 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
According to your code that Can you try change your hook and fetcher to: const { data, error } = useSWR(userToken ?
['/calendar/events', userToken, Array.isArray(date) ? date[0] : date, Array.isArray(date) ? date[1] : date] :
null,
fetch
); export function fetch(path, userToken, from, to) {
return API.get(path, {
params: {
from,
to,
},
headers: {
Authorization: `Bearer ${userToken}`,
},
}).then((data) => data);
} So the key array can be correctly serialized. |
Beta Was this translation helpful? Give feedback.
According to your code that
date
is an array of shape[startingDate, endingDate]
, so it might not have referential equality and will possible trigger unnecessary re-renders.Can you try change your hook and fetcher to:
So the key array can be correctly serialized.