์ฌ์ฉ์๊ฐ ์ ๊ทผ ๊ฐ๋ฅํ ์ต๋ ๋ผ์ฐํฐ๋ /messagebox/[userId]/[type]/[messageId]/[options] ์ธ๋ฐ, ๋ง์ง๋ง ๊ฒฝ๋ก [options]๋ ๋ณ๋ ฌ ๋ผ์ฐํ ์ผ๋ก ์์ฑํ๊ณ ๊ฒฝ๋ก ๊ฐ๋ก์ฑ๊ธฐ๋ฅผ ํตํด ํ์ด์ง ์์์ ๋์ฐ๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌํํ ํ์ด์ง์ ์ชฝ์ง์ ๋ํ ํผ๋๋ฐฑ์ ๋ณด๋ผ ์ ์๋ reaction ํ์ด์ง๊ฐ ์์ด์ ๊ฒฝ๋ก์ ๋ง์ถฐ ๊ธฐ๋ฅ์ ๊ตฌ๋ถํด์ผ ํ์ต๋๋ค.
์ฒ์์ ๋จ์ํ router.back()์ผ๋ก ํด๊ฒฐํ๋ ค ํ๋ ์ฌ์ฉ์ ์ ์ฅ์์ ๊ณ ๋ คํ์ ๋ ์๋ํ ๋ฐ๋ก ๋ค๋ก๊ฐ๊ธฐ๊ฐ ๋์ง ์๋ ๋ฌธ์ ๊ฐ ์์ด์, ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๊ธฐ ์ํด ๋ณต์กํ ๋ด๋น๊ฒ์ด์ ๋ก์ง์ ๊ด๋ฆฌํ๊ณ ํน์ ๊ฒฝ๋ก์์ ๋ค๋ก๊ฐ๊ธฐ ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํ ์ปค์คํ ํ ์ ๊ฐ๋ฐํ์ต๋๋ค.
์๋๋ router.back() ์ด์์ ๋ ํ์์ ๋๋ค
์ด์ ๊ฒฝ๋ก๋ฅผ ๊ธฐ์ตํ๋๋ก ํ๊ธฐ ์ํด์ ๊ฐ์ฅ ๋จผ์ ์๊ฐํด๋ณธ ๋ฐฉ๋ฒ์ ์๋ 2๊ฐ์ง์์ต๋๋ค.
- document.referrer
- ์ ์ญ ์ํ ๊ด๋ฆฌ
๊ทธ๋ฐ๋ฐ ์ ์ญ ์ํ๋ก ์ด์ ํ์ด์ง์ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋๋ก ํ๋ฉด ์๋ก๊ณ ์นจ๋์์ ๋์ ๊ฐ์ด ๋ธ๋ผ์ฐ์ ๋ฅผ ๋ซ์ง ์์๋๋ฐ ํน์ ์ํฉ์์ ์ ์ฅ๋ ๊ฐ๋ค์ด ํ๋ฐ๋ ์ ์์ ๊ฑฐ๋ผ๊ณ ์๊ฐํด์ ๋จผ์ 1๋ฒ์ผ๋ก ์๋ํ๊ฒ ๋์์ต๋๋ค.
โ ์๋ 1: document.referrer
๋ค์ ์ฌํญ์ ๊ณ ๋ คํ๊ณ ์งํํ์ต๋๋ค.
- ํ์ด์ง๊ฐ ์ด๋๋ ๋๋ง๋ค ์ด์ ๊ณผ ํ์ฌ ํ์ด์ง์ url๋ค์ ์ ์ฅํ๋๋กํด์ ๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ์ ๋๋ ์ ๋ ๊ทธ ์ด์ ์ ํ์ด์ง๋ก ์ด๋๋ ๊ฒ
- ๋ค๋ก๊ฐ๊ธฐ ๋๋ฉด ์ด๋๋ ์ฃผ์๋ ์ ์ฅ๋ชฉ๋ก์์ ์ญ์ ๋ ๊ฒ
- /messagebox/${userId}์์ ๋ค๋ก๊ฐ๊ธฐ ๋๋ฉด ํ ํ๋ฉด์ผ๋ก ๊ฐ๊ณ , ์ ์ฅ๋ ๋ชฉ๋ก์ด ๋ค ๋ ์๊ฐ ๊ฒ
useEffect(() => {
if (document.referrer.includes('/messagebox')) {
console.log(prevPath) // null ๋์ด
console.log(document.referrer) // ์ฒ์ ์ ๊ทผํ url ๋์ด
setPrevPath(document.referrer)
}
}, [pathname])
useEffect๋ก pathname์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๊ฐ์งํด์ ์ด๊ธฐ๊ฐ์ด null์ธ ๋ฌธ์์ด ๋ฐฐ์ด prevPath์ url์ ์ถ๊ฐํ๋๋ก ํ๊ณ , ๋ค๋ก ๊ฐ๊ธฐ ํ๋ฉด ๋ฐฐ์ด์์ ์ญ์ ๋๋๋ก ํ๋ฉด ํด๊ฒฐ๋๊ฒ ๋ค๊ณ ์์ํ ๊ฒ๊ณผ ๋ฌ๋ฆฌ, prevPath๊ฐ null๋ก ๊ด์ธก๋์์ต๋๋ค. document.referrer์ ๋ฐํ๊ฐ ๋ํ ๋ณ๊ฒฝ๋์ง ์๋ ๊ฒ์ ์ ์ ์์์ต๋๋ค.
๊ทธ ์ด์ ๋ก Next.js์์๋ ๋ด๋ถ ๋ผ์ฐํฐ๋ก ํ์ด์ง๋ฅผ ์ด๋ํ๊ธฐ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ๊ฐ ์ต์ด ์ง์ ํ ์ฃผ์๋ง ๊ฐ์ง๊ฐ ๊ฐ๋ฅํ์ง ์์๊น ์ถ์ธกํ์ต๋๋ค.
MDN ๋ฌธ์์๋ '๋งํฌ๋ฅผ ํตํด ํ์ฌ ํ์ด์ง๋ก ์ด๋์ํจ, ์ ํ์ด์ง์ URI ์ ๋ณด๋ฅผ ๋ฐํํ๋ค'๊ณ ๋์ด์์์ต๋๋ค.
โ ์๋ 2: Session Storage
๋ง์ง๋ง์ผ๋ก, ๋ธ๋ผ์ฐ์ ์น ์คํ ๋ฆฌ์ง ์์ฒด์ ์ด์ ์ ๊ทผ URL์ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ ์ฌ๋ ธ์ต๋๋ค.
๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ์ ์ฅํ๋ฉด ํญ์ ๋ซ์๋ ์ญ์ ๋์ง ์์์, ํญ์ ๋ซ๊ฑฐ๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ข ๋ฃํ๋ฉด ์์์ ํ๋ฐ๋๋ ์ธ์ ์คํ ๋ฆฌ์ง์ ์ ์ฅํ๋ ๊ฒ์ด ์ ํฉํ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก๋ ์คํ์ ๊ตฌํํด ์ธ์ ์ ์คํ ๋ฐฐ์ด์ ์ ์ฅํ๋ ํจ์๋ฅผ ํ ์ผ๋ก ๋ง๋ค์ด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค์ ์ฌํญ์ ๊ณ ๋ คํ์ต๋๋ค.
- ์ด์ ์ฃผ์๊ฐ๊ณผ ํ์ฌ ์ฃผ์๊ฐ์ด ๊ฐ์ผ๋ฉด ์ ์ฅํ์ง ์๋๋ค.
- /messagebox/[userId]/[type]/[messageId] ํ์ด์ง์ ์ ๊ทผํ๋ ๋ฃจํธ๊ฐ 2๊ฐ์ง์ธ ๊ฒ์ ๊ณ ๋ คํ๋ค.
- ์ ์ฃผ์๊ฐ 3๋ฒ์ด๋ผ๊ณ ๊ฐ์ ํ์ ๋ 3๋ฒ์ ๋๋ฌํ๋ ๋ฐฉ๋ฒ์ 1-> 2 -> 3, 1 -> 3 ์ด ์๋ค.
- [options]์์๋ /reaction ํ์ด์ง์ธ์ง ๋ชจ๋ฌ ํ์ด์ง์ธ์ง์ ๋ฐ๋ผ ์ฒ๋ฆฌํ๋ค.
- /[options] ๊ฒฝ๋ก๋ ๋ค๋ก๊ฐ๊ธฐ ์คํ์ ์ถ๊ฐ๋๋ฉด ์๋๋ค.
- /reaction ๋ POST ์์ฒญ์ ํ๋ api๊ฐ ์๋ ํ์ด์ง์ธ๋ฐ, ์์ฒญ ํ /messagebox/[userId]/[type]/[messageId] ๋ก ์ด๋๋๋ ๊ณผ์ ์ ๊ณ ๋ คํด์ผํ๋ค. ์ด๋๋ ํ์ด์ง์์ ๋ค๋ก๊ฐ๊ธฐ๋ฅผ ํ์ ๋ /reaction์ผ๋ก ๋์๊ฐ๋ฉด ์๋๋ค.
useEffect(() => {
const storage = globalThis?.sessionStorage
if (!storage) return
let pathStack = JSON.parse(storage.getItem('pathStack') || '[]')
const pathParts = pathname.split('/')
if (pathParts.length > 4) return
....
useEffect ํ ์ userId, pathname์ ์์กด์ฑ์ผ๋ก ์ฃผ์ ํ๊ณ globalThis?.sessionStorage๋ฅผ ํตํด ์ธ์ ์คํ ๋ฆฌ์ง๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ์ง ํ์ธํ๊ณ , ์ธ์ ์คํ ๋ฆฌ์ง์์ pathStack์ ๊ฐ์ ธ์์ JSON ํ์ฑํ์ฌ ๊ธฐ์กด์ ๊ฒฝ๋ก ์คํ์ ์ด๊ธฐํํ์ต๋๋ค.
[options]๋ฅผ ์ ์ธํ๊ณ ๊ฒฝ๋ก์ ์ต๋ ํํธ ์๊ฐ 4๊ฐ์ด๊ธฐ ๋๋ฌธ์ ๊ด๋ฆฌ์ฑ์ ๊ฐํํ๊ธฐ ์ํด 4๋ฅผ ์ด๊ณผํ๋ฉด ๋ ์ด์ ๊ฒฝ๋ก๋ฅผ ์ถ์ ํ์ง ์๋๋ก ์ค์ ํ์ต๋๋ค.
if (pathname === `/messagebox/${userId}`) {
storage.removeItem('pathStack')
pathStack = [pathname]
} else if (pathStack[pathStack.length - 1] !== pathname) {
if (pathParts.length >= 3) {
if (!pathStack.includes(pathname)) {
pathStack.push(pathname)
}
}
}
storage.setItem('pathStack', JSON.stringify(pathStack))
}, [pathname, userId])
/messagebox ์ด์ธ์ ๊ฒฝ๋ก์์๋ ๋ณต์กํ ๊ฒฝ๋ก ์ด๋์ด ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๊ฐ ํ์ฌ /messagebox/[userId] ๋ก ์ง์ ํ์ ๋๋ง์ ์กฐ๊ฑด์ ์ถ๊ฐํ์ต๋๋ค. ์ด๋ ์ด์ ๊ฒฝ๋ก๋ฅผ ์ง์ฐ๊ณ ์๋ก์ด ๊ฒฝ๋ก๋ก ์ด๊ธฐํํ๋๋ก ํฉ๋๋ค.
pathStack์์ ๋ง์ง๋ง ๊ฒฝ๋ก๊ฐ ํ์ฌ pathname๊ณผ ๋ค๋ฅด๋ฉด์ ์๋ก์ด ๊ฒฝ๋ก๊ฐ pathStack์ ์๋ ๊ฒฝ์ฐ์๋ง ์ถ๊ฐ๋๋๋ก ์กฐ๊ฑด์ ๋ง์กฑํ ๋๋ง pathStack ๋ฐฐ์ด์ pathname์ pushํ์ต๋๋ค.
์ต์ข ์ ์ผ๋ก ์ ๋ฐ์ดํธ๋ pathStack์ ๋ค์ ์ธ์ ์คํ ๋ฆฌ์ง์ ์ ์ฅํฉ๋๋ค.
interface navProps {
userId: string
messageId?: string
type?: MessageType
}
export const useBackHandler = ({ userId, type, messageId }: navProps) => {
const router = useRouter()
const pathname = usePathname()
const backHandler = () => {
const storage = globalThis?.sessionStorage
if (!storage) return
const pathStack = JSON.parse(storage.getItem('pathStack') || '[]')
const pathParts = pathname.split('/')
const lastSegment = pathParts[pathParts.length - 1]
if (pathname === `/messagebox/${userId}`) {
storage.removeItem('pathStack')
router.replace(`/home/${userId}`)
return
}
if (pathname === `/messagebox/${userId}/${type}/${messageId}`) {
router.replace(pathStack[pathStack.length - 1])
storage.setItem('pathStack', JSON.stringify(pathStack))
pathStack.pop()
return
}
if (lastSegment === 'reaction') {
const messagePagePath = pathParts.slice(0, -1).join('/')
router.replace(messagePagePath)
pathStack.pop()
return
}
if (pathParts.length > 4 && lastSegment !== 'reaction') {
router.replace(pathStack[pathStack.length - 1])
pathStack.pop()
return
}
if (pathStack.length > 1) {
pathStack.pop()
storage.setItem('pathStack', JSON.stringify(pathStack))
router.replace(pathStack[pathStack.length - 1])
}
router.back()
}
{/* ์์ useEffect */}
return backHandler
}
์ด์ ์กฐ๊ฑด ์ฒ๋ฆฌ๋ฅผ ํด์คฌ๋๋ฐ, ์์ ์ ๋ฆฌํ ์๊ตฌ์ฌํญ์ ๊ธฐ์ค์ผ๋ก ์กฐ๊ฑด์ ๋ง์กฑํ๋๋ก ์์ฑํ์ต๋๋ค.
/messagebox/[userId] ์์น์ ์์๋ ๋ค๋ก๊ฐ๊ธฐ ํ๋ฉด home์ผ๋ก ๋์๊ฐ๊ณ , session storage์ ์ ์ฅ๋์ด์๋ pathStack ์์ฒด๊ฐ ๋ ์๊ฐ๋๋ก ํ์ต๋๋ค.
pathStack์๋ ๋ฐฐ์ด์ ๋์ ๊ฐ์ ์ถ๊ฐํ๋ push ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ path๋ฅผ ์ถ๊ฐํ๋๋ก ํด์ /messagebox/[userId]/[type]/[messageId] ํ์ด์ง์ ์ ๊ทผํ๋ ๋ฃจํธ๊ฐ 2๊ฐ์ง์ฌ๋ ๋ฐฐ์ด์ ๋ง์ง๋ง ๊ฐ์ผ๋ก ๊ฒฝ๋ก๋ฅผ ๋์ฒด์ํจ ํ, ์ฌ์ฉํ ๊ฐ์ pathStack์์ ์ญ์ ํ๊ธฐ ์ํด pop ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
/messagebox ์ด์ธ์ ๊ฒฝ๋ก์์๋ ๋จ์ํ router.back()๋ง ํด์ค๋ ๋์๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ์กฐ๊ฑด์ ๋ชจ๋ ํด๋นํ์ง ์๋๋ค๋ฉด router.back()์ ํตํด ๋ค๋ก๊ฐ๊ธฐ๊ฐ ์๋ํ๊ฒ ๋ฉ๋๋ค.
์ด์ ์ฌ์ฉ์์ ์์๋๋ก ๋ค๋ก๊ฐ๊ธฐ๋ฅผ ํตํ ์ด๋์ด ์ด๋ฃจ์ด์ง๋๋ค.
'What I Learn' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
husky์ GitHub Actions์ ์ฌ์ฉํ CICD (2) | 2025.02.05 |
---|---|
Intersection Observer API๋ฅผ ์ฌ์ฉํด ๋ทฐํฌํธ๋ฅผ ๋ชจ๋ํฐ๋งํ๋ ์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ (0) | 2025.02.05 |
Next.js ๋ณ๋ ฌ ๋ผ์ฐํ & ๊ฒฝ๋ก ๊ฐ๋ก์ฑ๊ธฐ๋ฅผ ํตํ ๋ชจ๋ฌ ํ์ด์ง ๊ตฌํ 2 (0) | 2024.12.26 |
e.stopPropagation(), ์ด๋ฒคํธ ์ ํ ๋ฐฉ์ง (0) | 2024.12.10 |
format date as 'YYYY.MM.DD AMhh:mm' (0) | 2024.12.10 |