Skip to content

Commit

Permalink
perf(useUser): fewer 403 returns in API
Browse files Browse the repository at this point in the history
  • Loading branch information
aprendendofelipe committed Jun 7, 2022
1 parent 0443bfa commit 87bef1c
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 21 deletions.
9 changes: 6 additions & 3 deletions pages/_app.public.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ThemeProvider, BaseStyles, SSRProvider } from '@primer/react';
import { SWRConfig } from 'swr';
import { UserProvider } from 'pages/interface/hooks/useUser/index.js';

async function SWRFetcher(resource, init) {
const response = await fetch(resource, init);
Expand All @@ -16,9 +17,11 @@ function MyApp({ Component, pageProps }) {
}}>
<SSRProvider>
<ThemeProvider preventSSRMismatch colorMode="day">
<BaseStyles>
<Component {...pageProps} />
</BaseStyles>
<UserProvider>
<BaseStyles>
<Component {...pageProps} />
</BaseStyles>
</UserProvider>
</ThemeProvider>
</SSRProvider>
</SWRConfig>
Expand Down
6 changes: 2 additions & 4 deletions pages/interface/components/Header/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { useRouter } from 'next/router';
import { Header, Box, Button, ActionMenu, ActionList } from '@primer/react';
import { Header, Box, ActionMenu, ActionList } from '@primer/react';
import { CgTab } from 'react-icons/cg';
import { useUser } from 'pages/interface/index.js';

export default function HeaderComponent() {
const router = useRouter();
const { user, isLoading } = useUser();

return (
Expand Down Expand Up @@ -37,7 +35,7 @@ export default function HeaderComponent() {
</>
)}

{!isLoading && user.username && (
{user.username && (
<>
<Header.Item>
<ActionMenu>
Expand Down
71 changes: 59 additions & 12 deletions pages/interface/hooks/useUser/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,62 @@
import useSWR from 'swr';
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';

const UserContext = createContext();

export function UserProvider({ children }) {
const [user, setUser] = useState({});
const [isLoading, setIsLoading] = useState(true);
const [isValidating, setIsValidating] = useState(false);
const [error, setError] = useState(undefined);

useEffect(() => {
setUser(JSON.parse(localStorage.getItem('user')) || {});
}, []);

const fetchUser = useCallback(async () => {
try {
const response = await fetch('/api/v1/user');
if ([200, 304].includes(response.status)) {
const fetchedUser = await response.json();
localStorage.setItem('user', JSON.stringify(fetchedUser));
setUser(fetchedUser);
} else if (response.status == 403) {
localStorage.removeItem('user');
setUser({});
}
} catch (error) {
setError(error);
}
}, []);

useEffect(() => {
if (isValidating) {
(async () => {
if (user?.id) await fetchUser();
setIsValidating(false);
setIsLoading(false);
})();
}
}, [fetchUser, isValidating, user]);

useEffect(() => {
if (isLoading) {
setIsValidating(true);
}
}, [isLoading]);

const userContextValue = useMemo(() => {
return {
user,
isLoading,
isValidating,
error,
fetchUser
};
}, [user, isLoading, isValidating, error, fetchUser]);

return <UserContext.Provider value={userContextValue}>{children}</UserContext.Provider>;
}

export default function useUser() {
const { data, isLoading, isValidating, error } = useSWR('/api/v1/user', {
revalidateOnFocus: false,
revalidateOnReconnect: false,
});

return {
user: data,
isLoading: isLoading,
isValidating: isValidating,
error: error,
};
return useContext(UserContext);
}
22 changes: 20 additions & 2 deletions pages/login/index.public.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState, useRef } from 'react';
import { useState, useRef, useEffect } from 'react';
import { useRouter } from 'next/router';
import { DefaultLayout } from 'pages/interface/index.js';
import { DefaultLayout, useUser } from 'pages/interface/index.js';
import { FormControl, Box, Heading, Button, TextInput, Flash, Link, Text } from '@primer/react';

export default function Login() {
Expand All @@ -21,6 +21,23 @@ function LoginForm() {
const [isLoading, setIsLoading] = useState(false);
const [errorObject, setErrorObject] = useState(undefined);
const [capsLockWarningMessage, setCapsLockWarningMessage] = useState(false);
const { user, fetchUser } = useUser();

useEffect(() => {
(async () => {
await fetchUser();
})();
}, [fetchUser]);

useEffect(() => {
if (user.id && router) {
if (router.query?.redirect) {
router.push(router.query.redirect);
} else {
router.push('/publicar');
}
}
}, [user, router]);

function detectCapsLock(event) {
if (event.getModifierState('CapsLock')) {
Expand Down Expand Up @@ -62,6 +79,7 @@ function LoginForm() {
const responseBody = await response.json();

if (response.status === 201) {
fetchUser();
if (router.query?.redirect) {
router.push(router.query.redirect);
} else {
Expand Down

0 comments on commit 87bef1c

Please sign in to comment.