โœ๐Ÿป [Code Camp_TIL] 24์ผ์ฐจ: localStorage์— ํ† ํฐ ์ €์žฅํ•˜๊ธฐ, Next.js ๋ Œ๋”๋ง ์›๋ฆฌ, ๊ถŒํ•œ๋ถ„๊ธฐ, HOF & HOC

code_Jยท2023๋…„ 4์›” 23์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
30/41
post-thumbnail

์ง€๋‚œ์‹œ๊ฐ„์— ๋กœ๊ทธ์ธ์„ ํ•ด์„œ ํ† ํฐ์„ ๋ฐ›์•„์˜ค๊ณ , ๋กœ๊ทธ์ธ ์„ฑ๊ณต ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ์‹ค์Šต์„ ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋ฉด ํ† ํฐ์ด ์‚ฌ๋ผ์ง€๋Š” ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒํ–ˆ๋‹ค. ์™œ ์ด๋Ÿฐ ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒํ• ๊นŒ?

์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋ฉด ์ƒˆ๋กœ์šด html, css, js๋ฅผ ๋‹ค์‹œ ๋ฐ›์•„์˜ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด์ „์— ๊ทธ๋ ธ๋˜ state ๋ณ€์ˆ˜๋“ค์ด ์ดˆ๊ธฐํ™”๋˜์–ด accessToken์ด ์‚ฌ๋ผ์ง€๋Š” ๊ฒƒ์ด๋‹ค.

ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋ญ๊ฐ€ ์žˆ์„๊นŒ?

refresh token์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค! ํ•˜์ง€๋งŒ refresh token๋Š” ๋‚œ์ด๋„๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ ์ „์— localstorage์— ํ† ํฐ์„ ์ €์žฅํ•ด์„œ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์› ๋‹ค.

localstorage๋Š” ๋ธŒ๋ผ์šฐ์ € ์ €์žฅ์†Œ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.



ํ† ํฐ์„ localStorage์— ์ €์žฅํ•˜๊ธฐ


ํ† ํฐ์„ ๋ธŒ๋ผ์šฐ์ €์— ์ €์žฅํ•˜๋ฉด ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•ด๋„ ํ† ํฐ์ด ๋‚ ์•„๊ฐ€์ง€ ์•Š๋Š”๋‹ค.

localStorage.setItem(key, value)๋ฅผ ์ด์šฉํ•ด์„œ ๋กœ๊ทธ์ธ ํ›„์— ๋ฐ›์•„์˜จ accessToken์„ ๋ธŒ๋ผ์šฐ์ €์— ์ €์žฅํ•ด์ค€๋‹ค!

import {useMutation,gql} from "@apollo/client"
import {ChangeEvent} from "react"
import { useRecoilState } from "recoil";
import {useRouter} from "next/router"

cosnt LOGIN_USER = gql`
	mutation loginUser($email:String){
		loginUser(email: $email, password: $password){
			accessToken
		}
	}
`

export default function LoginPage(){
	cosnt [accessToken,setaccessToken] = useRecoilState(accessTokenState)
 
	const [email,setEmail]=useState("")
	const [password,setPassword]=useState("")
	const [loginUser] = useMutation<Pick<IMutation,'loginUser'>,IMutationLoginUserArgus>(LOGIN_USER)
	const router = useRouter()

	const onChangeEmail = (event:ChangeEvent<HTMLInputElement>)=>{
		setEmail(event.target.value)
		}
	const onChangePassword = (event:ChangeEvent<HTMLInputElement>)=>{
    setPassword(event.target.value)
		}

	const onClickLogin = async()=>{
	try{
		// 1. ๋กœ๊ทธ์ธํ•ด์„œ accessToken ๋ฐ›์˜ค๊ธฐ
		cosnt result = await loginUser({
			variables:{
					email : email,
					password : password
				}
			})
			const accessToken = result.data?.loginUser.accessToken

			// 2. accessToken์ด ์žˆ๋‹ค๋ฉด global state์— ์ €์žฅ ํ›„ localStorage์— ์ €์žฅํ•˜๊ธฐ
			if(accessToken){setAccessToken(accessToken || "" )
				void router.push('/loginsuccess')
localStorage.setItem("accessToken",accessToken) // ์ž„์‹œ๋กœ ์‚ฌ์šฉ ๋‚˜์ค‘์— ์ง€์šธ์˜ˆ์ •
			}
		}catch(error){
			Modal.error({content : error.message})
		}
	} 

	return(
		<div>
			์ด๋ฉ”์ผ : <input type="text" onchange={onChangeEmail}/> <br/>
			๋น„๋ฐ€๋ฒˆํ˜ธ : <input type="password" onchange={onChangePassword}/> 
			<button onClick={onClickLogin}>๋กœ๊ทธ์ธ</button>
		</div>
	)
}

์‹ค์ œ๋กœ accessToken์ด ์ €์žฅ๋˜๋Š” ๊ณณ์€ recoil์˜ recoilState์˜ accessToken์ด๋ผ๋Š” ๋ณ€์ˆ˜๋‹ค.

์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๊ฒŒ ๋˜๋ฉด accessToken ๋ณ€์ˆ˜๊ฐ€ ์ƒˆ๋กœ ๊ทธ๋ ค์ง€๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ login ํŽ˜์ด์ง€์—์„œ ๋ธŒ๋ผ์šฐ์ €์— ์ €์žฅํ•ด๋‘” accessToken์„ getItem์„ ํ†ตํ•ด ๊ฐ€์ ธ์™€, setAccessToken์— ๋‹ค์‹œ ๋„ฃ์–ด์ฃผ์–ด ๋ธŒ๋ผ์šฐ์ €์— ์ €์žฅ๋œ ํ† ํฐ์œผ๋กœ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•œ๋‹ค.

์ฐธ๊ณ ! localStorage ์‚ฌ์šฉ๋ฐฉ๋ฒ•

์ €์žฅํ•  ๋•Œ: localstorage.setItem("key", value)
๊บผ๋‚ด์˜ฌ ๋•Œ: localstorage.getItem("key")

ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ localstorage is not defined ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. next.js์˜ ๋ Œ๋”๋ง ๋ฐฉ์‹ ๋•Œ๋ฌธ์ด๋‹ค!


Next.js ๋ Œ๋”๋ง ์›๋ฆฌ

  1. ๋ธŒ๋ผ์šฐ์ €์— ์ฃผ์†Œ๋ฅผ ์ž…๋ ฅํ•ด์„œ ์ ‘์†ํ•˜๋ฉด, ํ”„๋ก ํŠธ์—”๋“œ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ html, css, js์„ ๋ฐ›์•„์˜จ๋‹ค.

  2. html์ด ๋จผ์ € ๋‹ค์šด๋ฐ›์•„์˜ค๊ณ , html์ด ๋ธŒ๋ผ์šฐ์ €์— ๊ทธ๋ ค์ง€๋ฉด์„œ css, js๋ฅผ ๋‹ค์šด๋ฐ›์•„์˜จ๋‹ค.

  3. html ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š”๋ฐ, ์šฐ๋ฆฌ๋Š” jsํŒŒ์ผ๋กœ๋งŒ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ ํ”„๋ก ํŠธ ์„œ๋ฒ„์—์„œ ๋จผ์ € ๊ทธ๋ ค๋ณธ๋‹ค(prerendering).

  4. ํ”„๋ฆฌ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ทธ๋ฆฌ๊ณ , ๊ทธ ํ›„์— js ํŒŒ์ผ์„ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋‹ค์šด๋ฐ›์•„์˜ค๊ณ , js ํŒŒ์ผ์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋‹ค์‹œ ์‹คํ–‰์‹œ์ผœ๋ณด๋ฉฐ ๋จผ์ € ๊ทธ๋ ธ๋˜ ๊ฒƒ๊ณผ ๋น„๊ต(diffing)ํ•ด๋ณธ๋‹ค.

  5. ๋น„๊ต(diffing)ํ•œ ํ›„์— ๋‹ค๋ฅธ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ์ตœ์ข…์ ์œผ๋กœ ๋ฐ˜์˜ํ•ด์„œ ๋ Œ๋”๋งํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ onClick, onChange ๋“ฑ ๊ธฐ๋Šฅ๋“ค์„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ฒŒ ๋œ๋‹ค. ์ด ๊ณผ์ •์„ hydration์ด๋ผ๊ณ  ํ•œ๋‹ค.


์ฆ‰, 2๋ฒˆ ๊ทธ๋ฆฌ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค! html๋งŒ ๋น ๋ฅด๊ฒŒ ๋ฐ›์•„์™€์„œ ๋ธŒ๋ผ์šฐ์ €์— ๊ทธ๋ ค์ฃผ๊ณ , ๊ทธ ํ›„์— js๋กœ ํ•œ ๋ฒˆ ๋” ๊ทธ๋ ค์ค€๋‹ค(hydration: ๋ฌผ ์ฃผ๊ธฐ).

์—ฌ๊ธฐ์„œ localstorage is not defined ์—๋Ÿฌ์˜ ์ด์œ ๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค. localstorage๋Š” ๋ธŒ๋ผ์šฐ์ €์—๋งŒ ์žˆ๋Š”๋ฐ, ์„œ๋ฒ„์—์„œ ๋จผ์ € prerendering ํ•˜๊ธฐ ๋•Œ๋ฌธ์— localstorage๋Š” ์‹คํ–‰์— ์‹คํŒจํ•œ๋‹ค.


useEffect๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๊ฒฐ!

useEffect๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ Œ๋”๋ง ์ดํ›„์— ์‹คํ–‰๋˜๋„๋ก ํ•˜๋ฉด ๋œ๋‹ค.

// Apollo Setting 

// ==import ๋ถ€๋ถ„ ์ƒ๋žต==

export default function ApolloSetting(props) {
	const [accessToken,setAccessToken] =useRecilState(accessTokenState)

	useEffect(()=>{
		if(localStorage.getItem("accessToken")){
		setAccessToken(localStorage.getItem("accessToken")||"")
	}
},[])

	const uploadLink = createUploadLink({
			uri : "๋ฐฑ์—”๋“œ ์ฃผ์†Œ",
			headers : { Authorization : "Bearer ๋ฐ›์•„์˜จ ํ† ํฐ" }
		})

	// ====== return ๋ถ€๋ถ„ ์ƒ๋žต =======
}

๊ถŒํ•œ๋ถ„๊ธฐ


๋กœ๊ทธ์ธ ์ธ์ฆ ์ดํ›„์—๋Š” ๊ถŒํ•œ ๋ถ„๊ธฐ๊ฐ€ ์ด๋ฃจ์–ด์ง„๋‹ค. ๋กœ๊ทธ์ธ์„ ํ•œ ์‚ฌ๋žŒ๊ณผ ํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ์œผ๋กœ ๋‚˜๋ˆ„๊ธฐ๋„ ํ•˜๊ณ , ์šด์˜์ž๋กœ ๋กœ๊ทธ์ธ ํ•œ ์‚ฌ๋žŒ, ํŒ๋งค์ž๋กœ ๋กœ๊ทธ์ธ ํ•œ ์‚ฌ๋žŒ ๋“ฑ์œผ๋กœ ๋‹ค์–‘ํ•˜๊ฒŒ ๊ถŒํ•œ์„ ๋ถ„๋ฆฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.


๊ถŒํ•œ๋ถ„๊ธฐ ์‚ฌ์ „์ง€์‹


์Šคํƒ๊ณผ ํ

์Šคํƒ์€ ์ถœ์ž…๊ตฌ๊ฐ€ ํ•˜๋‚˜์ธ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋‹ค.

๊ฐ€์žฅ ์ฒ˜์Œ์— ์ž…๋ ฅ๋œ ํ•จ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ๋‚˜์ค‘์— ์Šคํƒ์„ ๋น ์ ธ๋‚˜๊ฐ„๋‹ค(FILO: First In Last Out).


ํ๋Š” ์–‘๋ฐฉํ–ฅ ์ถœ์ž…์ด ๊ฐ€๋Šฅํ•œ ํŒŒ์ดํ”„ ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋‹ค.

๊ฐ€์žฅ ๋จผ์ € ์ž…๋ ฅ๋œ ํ•จ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ๋จผ์ € ๋น ์ ธ๋‚˜๊ฐ„๋‹ค(First In First Out).


์Šค์ฝ”ํ”„ ์ฒด์ธ

์Šค์ฝ”ํ”„ ์ฒด์ธ์ด๋ž€ ํ•ด๋‹น ์Šค์ฝ”ํ”„์— ์—†์œผ๋ฉด ์ƒ์œ„ ์Šค์ฝ”ํ”„๋กœ ์ฐพ์•„ ์˜ฌ๋ผ๊ฐ€๋Š” ๊ณผ์ •์„ ์˜๋ฏธํ•œ๋‹ค.


Closure

<!DOCTYPE html>
<html lang="ko">
	<head>
		<title>ํด๋กœ์ € ์‹ค์Šต</title>
		<script>
			function aaa(){
				const apple = 10

				function bbb(){
					console.log(apple)
				}
				bbb()
			}
			aaa();
		</script>
	</head>
	<body>
		ํด๋กœ์ € ์‹ค์Šต
	</body>
</html>

script tag ์•ˆ์ชฝ์„ ๋ณด๋ฉด, aaa()์™€ bbb()๊ฐ€ ์ฝœ์Šคํƒ์— ์Œ“์ด๊ณ , bbb()๊ฐ€ ์Šคํƒ์˜ ๊ฐ€์žฅ ์œ„์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ๋จผ์ € ์ฝœ์Šคํƒ์„ ๋น ์ ธ๋‚˜๊ฐ„๋‹ค.

bbb ํ•จ์ˆ˜์—์„œ apple์ด๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ฝ˜์†”์ฐฝ์— ๋„์šฐ๋ ค๊ณ  ํ•˜์ง€๋งŒ, bbb() ์•ˆ์—๋Š” apple์ด๋ผ๋Š” ๋ณ€์ˆ˜๊ฐ€ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ์Šค์ฝ”ํ”„์ฒด์ธ์ด ์ผ์–ด๋‚˜๊ณ  apple ๋ณ€์ˆ˜๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด aaa()๋ผ๋Š” ์ƒ์œ„ ์Šค์ฝ”ํ”„๋กœ ์˜ฌ๋ผ๊ฐ„๋‹ค.

์—ฌ๊ธฐ์„œ aaa ํ•จ์ˆ˜๋Š” bbb์˜ closure๊ฐ€ ๋œ๋‹ค. ์ฆ‰, ํด๋กœ์ €๋Š” ์ƒ์œ„ ํ•จ์ˆ˜์™€ ํ•ด๋‹น ํ•จ์ˆ˜(bbbํ•จ์ˆ˜)๊ฐ€ ์„ ์–ธ๋œ ์Šค์ฝ”ํ”„(์ƒ์œ„ํ•จ์ˆ˜๋ฅผ ๋‘˜๋Ÿฌ์‹ผ ํ™˜๊ฒฝ)์ด ๋œ๋‹ค.


HOF(High Order Function)


function aaa(){
	console.log("์ €๋Š” aaa์˜ˆ์š”")

	return function bbb(){
		console.log("์ €๋Š” bbb์˜ˆ์š”")
	}
}

์œ„์˜ ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๋กœ ์ฝ˜์†”์— "์ €๋Š” aaa์˜ˆ์š”"๊ฐ€ ์ถœ๋ ฅ์ด ๋˜๊ณ , ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ bbb ํ•จ์ˆ˜๊ฐ€ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ฝ˜์†”์— โ€œ์ €๋Š” bbb์˜ˆ์š”โ€๋ฅผ ์ถœ๋ ฅํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ๋ ๊นŒ?

๊ทธ๋Ÿฌ๋ ค๋ฉด bbbํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š”๋ฐ, ๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” aaa()()๋กœ ์ ์–ด์ฃผ๋ฉด ๋œ๋‹ค.


์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

function aaa(){
	const apple = 10

	return function bbb(){
		const banana = 5
		console.log(banana)
		console.log(apple)
	}
}

aaa()()

// ์‹คํ–‰ ๊ฒฐ๊ณผ
// 5
// 10

์œ„์˜ ํ•จ์ˆ˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ด์šฉํ•ด ์กฐ๊ธˆ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

// ํ•จ์ˆ˜ ์„ ์–ธ์‹
function aaa(apple){

	return function bbb(banana){
		console.log(banana)
		console.log(apple)
	}
}

aaa(10)(5)

// ์‹คํ–‰ ๊ฒฐ๊ณผ
// 5 => bbb์— ๋„ฃ์€ ์ธ์ž๊ฐ’
// 10 => aaa์— ๋„ฃ์€ ์ธ์ž๊ฐ’

์ด์ œ ์œ„์˜ ํ•จ์ˆ˜๋ฅผ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ๋ฐ”๊พธ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜ํƒ€๋‚ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ๋ณ€๊ฒฝ
const aaa = (apple)=>{
	return (banana)=>{
				console.log(apple)
				console.log(banana)
		}
}

aaa(10)(5)

์ค‘๊ด„ํ˜ธ์™€ return ์‚ฌ์ด์— ์•„๋ฌด๊ฒƒ๋„ ์—†๋‹ค๋ฉด ์ค‘๊ด„ํ˜ธ๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

// ์ค‘๊ด„ํ˜ธ ์ƒ๋žต
const aaa = (apple)=>(banana)=>{
				console.log(apple)
				console.log(banana)
}

aaa(10)(5)

HOC(Higher Order Component)

HOC๋Š” ์ƒ์œ„์— ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋กœ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋ณด๋‹ค ๋จผ์ € ์‹คํ–‰๋˜๋Š” ์ปดํฌ๋„ŒํŠธ๋‹ค.

HOC๋Š” ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์— ์ ํ•ฉํ•œ ๋ฐฉ์‹์ด๋‹ค. ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์— ์ ํ•ฉํ•œ ๋ฐฉ์‹์€ ๋‚˜์ค‘์— ๋ฐฐ์šธ ์˜ˆ์ •์ด๋‹ค.


๊ถŒํ•œ ์ฒดํฌํ•˜๋Š” withAuth ๋งŒ๋“ค๊ธฐ

๊ถŒํ•œ์„ ์ฒดํฌํ•˜๋Š” HOC๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์–ด๋ณด์•˜๋‹ค.

export const withAuth = (Component:any)=>(props:any)=>{
	const router = useRouter()
	useEffect(()=>{
		if(!localStorage.getItem("accessToken")){
			alert("๋กœ๊ทธ์ธ์„ ๋จผ์ € ํ•ด์ฃผ์„ธ์š”")
			void router.push("/๋กœ๊ทธ์ธ ํŽ˜์ด์ง€")
		}
	},[])

	return <Component {...props} />
}

์ด์ œ ๊ถŒํ•œ ์ฒดํฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์€ ํŽ˜์ด์ง€์— ์ ์šฉํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

// loginSuccessPage -> withAuth ์ ์šฉํ•˜๊ธฐ 
const LoginSuccessPage = ()=>{
	const {data} = useQuery(FETCH_USER_LOGGED_IN)

	return <div>{data?.fetchUserLoggedIn.name}๋‹˜ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.</div>
}

export default withAuth(LoginSuccessPage)

์œ„์™€ ๊ฐ™์ด withAuth(์ ์šฉํ•˜๊ณ  ์‹ถ์€ ์ปดํฌ๋„ŒํŠธ) ํ˜•์‹์œผ๋กœ export ํ•ด์ฃผ๋ฉด ๋œ๋‹ค!

์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ๊ถŒํ•œ์ฒดํฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋จผ์ € ์‹คํ–‰๋œ๋‹ค.



profile
Web FE ๊ฐœ๋ฐœ์ž ์ทจ์ค€์ƒ

0๊ฐœ์˜ ๋Œ“๊ธ€