๐ ๋๊นกํ_08: "localStorage is not defined" in Next.js with js-cookie
์งํ ์ํฉ
list-followers.tsx
- js-cookie ์ค์น
- Cookie์ ์ ์ฅ๋ accountname, token ์ด์ฉ
- follower list API ์ฐ๋
๐ธ How to Fix "localStorage is not defined" in Next.js
Next.js์์ localStorage๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํ ๋ ๋ค์๊ณผ ๊ฐ์ ์๋ฌ๊ฐ ๋ํ๋๋ค.
ReferenceError: localStorage is not defined
์๋ฌ๊ฐ ๋ฐ์ํ๋ ์ด์
- Next.js๋ client-side๋ฅผ ๋ ๋ํ๊ธฐ ์ server-side ๋ ๋๋ฅผ ์ํํ๋ค.
- Next.js์์ ์ ๊ณตํ๋ Server Side Rendering(SSR)์์๋
window
,document
๊ฐ์ ๋ธ๋ผ์ฐ์ ์ ์ญ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์๋ค. - window ๊ฐ์ฒด๋ client-side์๋ง ์กด์ฌํ๋ค.
=> ๋ฐ๋ผ์, ํ์ด์ง๊ฐ client์ ๋ก๋๋๊ณ window
๊ฐ์ฒด๊ฐ ์ ์๋ ๋๊น์ง localStorage
์ ์ ๊ทผํ ์ ์๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ
typeof window !== 'undefined'
- ํ์ด์ง๊ฐ client์ ๋ง์ดํธ๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ
localStorage
์ ๊ทผํด์ผํ๋ค. window
๊ฐ์ฒด๊ฐ ์ฐธ์กฐ๋์ง ์์ ๊ฒฝ์ฐ,undefined
๋ฅผ ๋ฐํํ๋ค.localStorage
์ ์ ๊ทผํ๊ธฐ ์ ์localStorage
๊ฐ ์ ์๋๋ค.
if (typeof window !== 'undefined') {
// Perform localStorage action
const item = localStorage.getItem('key');
}
useEffect
useEffect
๋ ๋ ๋๋ง ์ ์คํ๋๋ฏ๋ก, ์ด๊ธฐ ์๋ฒ ๋น๋ ์useEffect
๋ด๋ถ ์ฝ๋๋ ์คํ๋์ง ์์useEffect
๋ client side์์๋ง ์คํ๋๋ฏ๋กlocalStorage
์ ์์ ํ๊ฒ ์ ๊ทผ ๊ฐ๋ฅ
import { useEffect } from "react";
useEffect(() => {
// Perform localStorage action
const item = localStorage.getItem('key')
}, [])
์ฐธ๊ณ ๋งํฌ
๐ js-cookie
- ์ฟ ํค๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ์ฟ ํค ๋ผ์ด๋ธ๋ฌ๋ฆฌ
๐ธ ์ค์น
npm i js-cookie
# yarn์ผ๋ก ์ค์นํ ๊ฒฝ์ฐ
yarn add js-cookie
TypeScript declarations
- TypeScript ์ฌ์ฉ์ ํ์ ์ ์ธ ํจํค์ง๋ ์ค์น
npm install --save @types/js-cookie
# yarn์ผ๋ก ์ค์นํ ๊ฒฝ์ฐ
yarn add @types/js-cookie
ES Module
- ๋ค๋ฅธ ๋ชจ๋์์ ES ๋ชจ๋์ import ํ๋ ๋ฐฉ๋ฒ
import Cookies from 'js-cookie'
Cookies.set('foo', 'bar')
ES Module
- ES6์ ๋์ ๋ ๋ชจ๋ ์์คํ
- import, export๋ฅผ ์ฌ์ฉํด ๋ถ๋ฆฌ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ๋ผ๋ฆฌ ์๋ก ์ ๊ทผํ ์ ์๋ค.
- ์ฐธ๊ณ ๋งํฌ: ES Modules ์ ๋ฆฌํ๊ธฐ
=> ES Module ๋ด์ฉ ์ ๋ฆฌํ๊ธฐ
์ฌ์ฉ๋ฒ
- ์ฟ ํค ๊ตฝ๊ธฐ
// ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
Cookies.set('name', 'value')
// ๋ง๋ฃ ๊ธฐ๊ฐ ์ค์ : ์ง๊ธ๋ถํฐ 7์ผ ํ ๋ง๋ฃ
Cookies.set('name', 'value', { expires: 7 })
- ๊ตฌ์ด ์ฟ ํค ๊ฐ์ ธ์ค๊ธฐ
Cookies.get('name') // => 'value'
Cookies.get('nothing') // => undefined
// ๋ชจ๋ ์ฟ ํค ๊ฐ์ ธ์ค๊ธฐ
Cookies.get() // => { name: 'value' }
- ๊ตฌ์ด ์ฟ ํค ์ญ์
Cookies.remove('name')
expires
- ์ฟ ํค ๋ง๋ฃ ๊ธฐ๊ฐ์ ์ ์
- ์๋ตํ๋ฉด ์ฟ ํค๊ฐ ์ธ์ ์ฟ ํค๊ฐ ๋๋ค.
- Default : ์ฟ ํค๋ ์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ๋ฅผ ๋ซ์ ๋ ์ ๊ฑฐ๋๋ค.
Cookies.set('name', 'value', { secure: true })
Cookies.get('name') // => 'value'
Cookies.remove('name')
๐ธ ์ด๋ฉ์ผ๋ก ๋ก๊ทธ์ธํ๋ ํ์ด์ง ์ฝ๋
- ๊ธฐ์กด localStorage์์ Cookie๋ก ๋ณ๊ฒฝ
const router = useRouter();
// ์ ์ฅ๋ token์ด ์์ ๊ฒฝ์ฐ (๋ก๊ทธ์ธ ์ํ์ธ ๊ฒฝ์ฐ)
if (Cookies.get('token')) {
// ํ์ผ๋ก ์ด๋
router.push('/home');
}
// submit button ํด๋ฆญ
const onSubmit = handleSubmit(async (userData) => {
const { data } = await axios(`${API_ENDPOINT}/user/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
user: {
email: userData.email,
password: userData.password,
},
}),
});
// error message๊ฐ ์์ ๊ฒฝ์ฐ,
if (data.message) {
// ์๋ฌ ๋ฉ์์ง๋ฅผ ๋ณด์ฌ์ค๋ค.
setLoginError('์ด๋ฉ์ผ ๋๋ ๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค.');
} else {
// ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ์ ์ ์ accountname, token์ ์ฟ ํค์ ์ ์ฅ
Cookies.set('accountname', data.user.accountname);
Cookies.set('token', data.user.token);
}
});
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ ๋๊นกํ_08: "localStorage is not defined" in Next.js with js-cookie), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@qhflrnfl4324/๋๊นกํ08-js-cookie์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค