preview
- 고차 함수랑 개념이 같음
- 함수 이름은 with로 시작하는것이 관습
authontication처리를 HOC로 해보자
- HOC pattern with Typescript
withAuthCheck.tsx
import { useEffect, ComponentType } from 'react'
import { useSelector } from 'react-redux'
import { RootState } from 'store/store'
import notify from 'components/utils/toast'
import { useNavigate } from 'react-router-dom'
interface WrappedProps {}
const withAuthCheck = <P extends WrappedProps>(
// wrappedComponent에서 전달 받은 props를 HOC에서 사용할 수 있다
WrappedComponent: ComponentType<P>,
) => {
const Component = (props: P) => {
const isLogin = useSelector((state: RootState) => state.users.isLogin)
const navigate = useNavigate()
useEffect(() => {
if (!isLogin) {
notify({
title: '잘못된 접근입니다.',
type: 'error',
})
navigate('/')
}
}, [isLogin, navigate])
return <WrappedComponent {...props} />
}
return Component
}
export default withAuthCheck
- 사용법
DashboardLayout.tsx(로그인해야지만 접근 가능한 path)
import React, { useState } from 'react'
import { Outlet } from 'react-router-dom'
import { styled } from '@mui/material/styles'
import DashboardSidebar from './DashboardSidebar'
import withAuthCheck from 'components/HOC/withAuthCheck'
const APP_BAR_MOBILE = 64
const APP_BAR_DESKTOP = 92
const RootStyle = styled('div')({
display: 'flex',
minHeight: '100%',
overflow: 'hidden',
})
const MainStyle = styled('div')(({ theme }) => ({
flexGrow: 1,
overflow: 'auto',
minHeight: '100%',
paddingTop: APP_BAR_MOBILE + 24,
paddingBottom: theme.spacing(10),
[theme.breakpoints.up('lg')]: {
paddingTop: APP_BAR_DESKTOP + 24,
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(2),
},
}))
const DashboardLayout = () => {
const [open, setOpen] = useState(false)
return (
<RootStyle>
{/* <DashboardNavbar onOpenSidebar={() => setOpen(true)} /> */}
<DashboardSidebar
isOpensidebar={open}
onCloseSidebar={() => setOpen(false)}
/>
<MainStyle>
<Outlet />
</MainStyle>
</RootStyle>
)
}
export default withAuthCheck(DashboardLayout)