정리
- useState()는 간단한 상태 공유에는 적합하지만, 전역 상태 관리에는 한계가 있음
- useRequestHeaders()는 서버에서 요청 헤더를 가져오지만, 클라이언트에서는 사용할 수 없음
- clearNuxtState()는 useState() 상태를 초기화하지만, 모든 상태를 지우면 성능 저하 가능
- 대규모 애플리케이션에서는 Pinia를 사용하여 더 체계적으로 상태를 관리하는 것이 적절함
useState() - 상태 공유
useState()는 Nuxt에서 상태를 저장하고 공유하는 함수입니다. Vue의 ref()와 비슷하지만, Nuxt의 전체 애플리케이션에서 SSR(서버 사이드 렌더링) 친화적으로 작동합니다.
SSR 친화적인 상태 관리
Nuxt에서 useState()는 SSR 시점에서 상태를 생성하고, 클라이언트로 하이드레이션(hydration)할 때 동일한 상태를 유지할 수 있도록 설계되었습니다.
- 서버 사이드에서 useState()로 정의된 상태는 useNuxtApp().payload.state에 저장됩니다.
- 클라이언트가 서버에서 렌더링된 페이지를 받을 때, 해당 상태가 JSON 형태로 직렬화되어 클라이언트 측에서 동일한 상태를 유지합니다.
- Nuxt는 페이지가 이동해도 기존 상태를 유지할 수 있도록 useState()의 키를 기반으로 관리합니다.
- 따라서 서버에서 생성된 상태가 클라이언트에서 사라지지 않고 유지되므로, SSR에서 상태를 지속적으로 유지하는 데 유용합니다.
사용법
const count = useState<number>('count', () => 0);
- 첫 번째 매개변수: 상태의 고유 키 (문자열)
- 두 번째 매개변수: 상태의 초기값을 설정하는 함수 (선택 사항)
useState()의 한계
useState()는 전역 상태 관리 라이브러리가 아닙니다. 즉, 컴포넌트 간 상태 공유는 가능하지만, 대규모 애플리케이션의 전역 상태 관리에는 적합하지 않습니다.
- 전역적인 구조 부족: 여러 개의 상태를 체계적으로 관리하기 어려움.
- 액션 및 뮤테이션 미지원: 상태 변경 로직이 분리되지 않아 유지보수가 어려움.
- 비동기 상태 관리 부족: 복잡한 비동기 작업을 처리하기 어려움.
- 클래스, 함수, 심볼 등의 직렬화 불가능: 내부적으로 JSON 직렬화를 사용하기 때문.
useRequestHeaders() - 요청 헤더 가져오기
useRequestHeaders()는 서버 사이드에서 요청 헤더에 접근하는 함수입니다. 인증 토큰이나 사용자 정보를 API 요청 시 사용할 때 유용합니다.
사용법
const headers = useRequestHeaders();
const headersWithCookie = useRequestHeaders(['cookie']);
- 브라우저에서는 빈 객체 {}를 반환합니다.
API 요청과 함께 사용하기
const headers = useRequestHeaders(['authorization']);
const data = await $fetch('/api/protected', { headers });
클라이언트 사이드에서는 동작하지 않음
if (process.client) {
const headers = useRequestHeaders(); // {} (빈 객체 반환)
}
clearNuxtState() - 상태 초기화
clearNuxtState()는 useState()로 생성된 모든 상태를 초기화합니다. 로그아웃 시 상태를 리셋하거나 특정 조건에서 초기 상태를 유지할 때 유용합니다.
사용법
clearNuxtState();
✅ 특정 상태만 초기화하려면 키를 지정할 수 있습니다.
clearNuxtState(['count', 'user']);
⚠️ 클라이언트에서만 동작하며 SSR 상태에는 영향을 주지 않습니다.
Pinia
Pinia는 Vue의 공식 상태 관리 라이브러리로, useState()보다 더 강력한 전역 상태 관리 기능을 제공합니다.
useState() vs Pinia
기능 | useState() | Pinia |
컴포넌트 간 공유 | ✅ | ✅ |
SSR 지원 | ✅ | ✅ |
구조화된 상태 관리 | ❌ | ✅ |
상태 변경 액션 지원 | ❌ | ✅ |
비동기 처리 | ❌ | ✅ |
개발자 도구 지원 | ❌ | ✅ |
설치
npm install pinia @pinia/nuxt
pinia
- Vue의 상태 관리 라이브러리
- Vue 3 및 Nuxt 3에서 사용할 수 있으며, 상태 저장(store) 및 공유 기능을 제공한다.
- Nuxt 환경에서 자동으로 플러그인을 등록하지 않습니다.
@pinia/nuxt
- Nuxt에서 Pinia를 자동으로 등록하고 최적화하는 Nuxt 전용 모듈이다.
- nuxt.config.ts의 modules에 추가하면 자동으로 Pinia가 Nuxt 플러그인으로 등록된다.
- SSR (서버사이드 렌더링) 환경에서도 Pinia가 올바르게 작동하도록 설정해준다.
nuxt.config.ts 설정
설치 후 nuxt.config.ts에서 modules에 @pinia/nuxt를 추가해야 합니다.
이렇게 하면 Pinia가 자동으로 Nuxt 플러그인으로 등록되므로, 별도의 createPinia() 설정 없이 사용할 수 있습니다.
export default defineNuxtConfig({
modules: ['@pinia/nuxt'],
});
스토어 생성
//스토어 생성 (store/counter.ts)
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
doubleCount: (state) => state.count * 2
},
actions: {
increment() {
this.count++;
},
async fetchCount() {
const data = await fetch('/api/count').then(res => res.json());
this.count = data.count;
}
}
});
// 컴포넌트에서 사용하기
<script setup>
import { useCounterStore } from '~/store/counter';
const counter = useCounterStore();
counter.increment();
</script>
Pinia 상태를 localStorage에 저장 (Persist)
기본적으로 Pinia는 상태를 페이지를 새로고침하면 초기화합니다. 상태를 localStorage에 저장하여 유지하려면 pinia-plugin-persistedstate를 추가하면 됩니다.
pnpm install pinia-plugin-persistedstate
nuxt.config.ts에 플러그인 추가
import { defineNuxtConfig } from 'nuxt/config'
export default defineNuxtConfig({
modules: [
"@pinia/nuxt",
"pinia-plugin-persistedstate/nuxt",
],
});
store/counter.ts에서 persist 설정 추가
피니아 공식 문서: https://prazdevs.github.io/pinia-plugin-persistedstate/frameworks/nuxt.html
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
persist: true, // 상태를 쿠키에 저장
});
세션스토리지나 로컬 스토리지를 사용할 경우 하이드레이션 미스 매치가 발생한다. 때문에 ClientOnly를 사용해야한다.
persist: {
// 로컬 스토리지 사용
// 하이드레이션 미스 매치 발생
storage: piniaPluginPersistedstate.localStorage(),
// 세션 스토리지 사용
// 하이드레이션 미스 매치 발생
storage: piniaPluginPersistedstate.sessionStorage(),
}
'Javascript > NuxtJS' 카테고리의 다른 글
[Nuxt3] storeToRefs() (0) | 2025.03.12 |
---|---|
[Nuxt3] ref()와 computed() 차이점 (0) | 2025.03.12 |
[Nuxt3] 라우트 미들웨어 (0) | 2025.03.09 |
[Nuxt3] 에러 핸들링 (0) | 2025.03.09 |
[Nuxt3] 플러그인 (0) | 2025.03.09 |