Перестает грузиться страница после объявления singOut
У меня есть файл с кодом для авторизации. В нем я описал функцию singOut, которая выход с аккаунта, но когда объявляю ее в другом файле (Файл с navbar, в котором как раз таки кнопка, к которой я привяжу действие выхода с аккаунта), то сайт перестает грузиться.
(Вставил весь код из файла с авторизацией, а то вдруг, что-то упустила)
import { useEffect } from 'react'
import { AxiosResponse } from 'axios'
import { useDispatch, useSelector } from 'react-redux'
import axios from '../utils/axios'
import { RootState } from '../types/redux.types'
import { Nullable, Tuple } from '../types/utility.types'
import { useLocalStorage } from './local-storage.hook'
import {
signInFailure,
signInStart,
signInSuccess,
signOut as signOutAction,
} from '../redux/slices/auth-slice'
import { LoginResponse, UserMeResponse } from '../types/hooks.types'
import { Role } from '../types/enums.types'
function toFormData(pairs: Array<Tuple<string, any>>) {
const params = new URLSearchParams()
pairs.forEach(([k, v]) => params.append(k, v))
return params
}
export function useAuth() {
const [storedUsername, setStoredUsername] = useLocalStorage<Nullable<string>>(
'username',
null
)
const [storedPassword, setStoredPassword] = useLocalStorage<Nullable<string>>(
'password',
null
)
const [storedToken, setStoredToken] = useLocalStorage<Nullable<string>>(
'token',
null
)
const [storedExpriresIn, setStoredExpriresIn] = useLocalStorage<number>(
'expiresIn',
0
)
const dispatch = useDispatch()
const { isSignedIn, loading, token, user } = useSelector(
(state: RootState) => state.auth
)
const tokenLifetime = 60 * 30 * 1000
const isSuperadmin = user?.role === Role.Superadmin
const isAliveToken = storedExpriresIn > Date.now()
useEffect(() => {
;(async () => {
try {
if (storedToken && isAliveToken) {
dispatch(signInStart())
const response: AxiosResponse<UserMeResponse> = await axios.get(
'/users/me',
{ headers: { Authorization: `bearer ${storedToken}` } }
)
const { data: user } = response
dispatch(
signInSuccess({
token: storedToken,
user: {
...user,
city: user.city_id,
isActive: user.is_active,
role: user.is_superuser ? Role.Superadmin : Role.Admin,
},
})
)
}
} catch (e) {
dispatch(signInFailure(e.message))
if (storedUsername && storedPassword) {
await signIn(storedUsername, storedPassword)
}
console.warn(e)
}
})()
}, [])
useEffect(() => {
if (token) {
axios.defaults.headers = {
...axios.defaults.headers,
Authorization: `bearer ${token}`,
}
}
}, [token])
async function signIn(username: string, password: string) {
try {
dispatch(signInStart())
const credentials = toFormData([
['username', username],
['password', password],
])
const {
data: { access_token: token },
}: AxiosResponse<LoginResponse> = await axios.post(
'/auth/jwt/login',
credentials,
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
)
const response: AxiosResponse<UserMeResponse> = await axios.get(
'/users/me',
{ headers: { Authorization: `bearer ${token}` } }
)
const { data: user } = response
setTimeout(() => {
dispatch(
signInSuccess({
token,
user: {
...user,
city: user.city_id,
isActive: user.is_active,
role: user.is_superuser ? Role.Superadmin : Role.Admin,
},
})
)
}, 550)
setStoredUsername(username)
setStoredPassword(password)
setStoredToken(token)
setStoredExpriresIn(Date.now() + tokenLifetime)
setTimeout(async () => {
await signOut()
}, tokenLifetime)
} catch (e) {
console.error(e)
dispatch(signInFailure({ error: e instanceof Error ? e.message : e }))
}
}
function signOut() {
dispatch(signOutAction())
setStoredUsername(null)
setStoredPassword(null)
setStoredToken(null)
setStoredExpriresIn(0)
}
return { signIn, signOut, user, loading, token, isSignedIn, isSuperadmin }
}
(Файл с navbar, строчка, после которой сайт перестает грузиться закомменчена)
import clsx from 'clsx'
import {
makeStyles,
Theme,
createStyles,
AppBar,
Toolbar,
IconButton,
Container,
Box,
Hidden,
Button,
Typography
} from '@material-ui/core'
import { MenuOutlined as MenuIcon } from '@material-ui/icons'
import { NavbarLogo } from './NavbarLogo'
import { Drawer } from '../drawer/Drawer'
// import { ThemeToggler } from './ThemeToggler'
import { DrawerProps } from '../../../types/components.types'
import { useAuth } from '../../../hooks/auth.hook'
const drawerWidth = 240
const useStyles = makeStyles((theme: Theme) =>
createStyles({
appBar: {
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
appBarShift: {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
menuButton: {
marginRight: 36,
},
hide: {
display: 'none',
},
row: {
display: 'flex',
alignItems: 'center',
},
toolbar: {
justifyContent: 'space-between',
},
})
)
export const Navbar: React.FC<DrawerProps> = ({ opened, onToggle }) => {
const classes = useStyles()
//const { signOut } = useAuth()
return (
<>
<AppBar
position="fixed"
className={clsx(classes.appBar, {
[classes.appBarShift]: opened,
})}
>
<Container>
<Toolbar className={classes.toolbar}>
<Hidden mdUp>
<Box className={classes.row}>
{!opened && (
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
onClick={onToggle}
>
<MenuIcon />
</IconButton>
)}
</Box>
</Hidden>
<Box display="flex" alignItems="center">
<Typography variant="h6">
{'Dashboard'}
</Typography>
</Box>
<Box>
<Button variant="contained" color="secondary">
{'Выход'}
</Button>
</Box>
</Toolbar>
</Container>
</AppBar>
<Drawer opened={opened} onToggle={onToggle} />
</>
)
}