상태 관리
Nuxt는 강력한 상태 관리 라이브러리와 useState 컴포저블을 제공하여 반응형이며 SSR에 적합한 공유 상태를 생성할 수 있습니다.
Nuxt는 useState 컴포저블을 제공하여 컴포넌트 간에 반응형이며 SSR에 적합한 공유 상태를 생성할 수 있습니다.
useState는 SSR에 적합한 ref 대체제입니다. 이 값은 서버 사이드 렌더링 후(클라이언트 사이드 하이드레이션 중)에도 보존되며, 고유한 키를 사용하여 모든 컴포넌트에서 공유됩니다.
useState 내부의 데이터는 JSON으로 직렬화되므로, 클래스, 함수, 심볼 등 직렬화할 수 없는 것이 포함되지 않도록 주의해야 합니다.베스트 프랙티스
const state = ref()를 <script setup> 또는 setup() 함수 외부에 정의하지 마세요.예를 들어,
export myState = ref({})와 같이 하면 서버에서 요청 간에 상태가 공유되어 메모리 누수가 발생할 수 있습니다.대신
const useX = () => useState('x')를 사용하세요.예시
기본 사용법
이 예시에서는 컴포넌트 로컬 카운터 상태를 사용합니다. useState('counter')를 사용하는 다른 컴포넌트도 동일한 반응형 상태를 공유합니다.
app.vue
<script setup lang="ts">
const counter = useState('counter', () => Math.round(Math.random() * 1000))
</script>
<template>
<div>
Counter: {{ counter }}
<button @click="counter++">
+
</button>
<button @click="counter--">
-
</button>
</div>
</template>
Read and edit a live example in Docs > Examples > Features > State Management.
전역적으로 캐시된 상태를 무효화하려면
clearNuxtState 유틸을 참고하세요.상태 초기화
대부분의 경우, 비동기로 해결되는 데이터로 상태를 초기화하고 싶을 것입니다. 이를 위해 app.vue 컴포넌트와 callOnce 유틸을 사용할 수 있습니다.
app.vue
<script setup lang="ts">
const websiteConfig = useState('config')
await callOnce(async () => {
websiteConfig.value = await $fetch('https://my-cms.com/api/website-config')
})
</script>
이것은 Nuxt 2의
nuxtServerInit 액션과 유사하며, 페이지 렌더링 전에 서버 사이드에서 스토어의 초기 상태를 채울 수 있습니다.Pinia와 함께 사용하기
이 예시에서는 Pinia 모듈을 활용하여 전역 스토어를 만들고 앱 전체에서 사용합니다.
Pinia 모듈을
npx nuxt module add pinia로 설치하거나 모듈 설치 가이드를 따라 설치해야 합니다.export const useWebsiteStore = defineStore('websiteStore', {
state: () => ({
name: '',
description: ''
}),
actions: {
async fetch() {
const infos = await $fetch('https://api.nuxt.com/modules/pinia')
this.name = infos.name
this.description = infos.description
}
}
})
<script setup lang="ts">
const website = useWebsiteStore()
await callOnce(website.fetch)
</script>
<template>
<main>
<h1>{{ website.name }}</h1>
<p>{{ website.description }}</p>
</main>
</template>
고급 사용법
import type { Ref } from 'vue'
export const useLocale = () => {
return useState<string>('locale', () => useDefaultLocale().value)
}
export const useDefaultLocale = (fallback = 'en-US') => {
const locale = ref(fallback)
if (import.meta.server) {
const reqLocale = useRequestHeaders()['accept-language']?.split(',')[0]
if (reqLocale) {
locale.value = reqLocale
}
} else if (import.meta.client) {
const navLang = navigator.language
if (navLang) {
locale.value = navLang
}
}
return locale
}
export const useLocales = () => {
const locale = useLocale()
const locales = ref([
'en-US',
'en-GB',
...
'ja-JP-u-ca-japanese'
])
if (!locales.value.includes(locale.value)) {
locales.value.unshift(locale.value)
}
return locales
}
export const useLocaleDate = (date: Ref<Date> | Date, locale = useLocale()) => {
return computed(() => new Intl.DateTimeFormat(locale.value, { dateStyle: 'full' }).format(unref(date)))
}
<script setup lang="ts">
const locales = useLocales()
const locale = useLocale()
const date = useLocaleDate(new Date('2016-10-26'))
</script>
<template>
<div>
<h1>Nuxt birthday</h1>
<p>{{ date }}</p>
<label for="locale-chooser">다른 로케일 미리보기</label>
<select id="locale-chooser" v-model="locale">
<option v-for="locale of locales" :key="locale" :value="locale">
{{ locale }}
</option>
</select>
</div>
</template>
Read and edit a live example in Docs > Examples > Advanced > Locale.
공유 상태
자동 임포트되는 컴포저블을 사용하면 전역 타입 안전 상태를 정의하고 앱 전체에서 임포트하여 사용할 수 있습니다.
composables/states.ts
export const useColor = () => useState<string>('color', () => 'pink')
app.vue
<script setup lang="ts">
// ---cut-start---
const useColor = () => useState<string>('color', () => 'pink')
// ---cut-end---
const color = useColor() // useState('color')와 동일
</script>
<template>
<p>현재 색상: {{ color }}</p>
</template>
서드파티 라이브러리 사용하기
Nuxt는 이전에는 전역 상태 관리를 위해 Vuex 라이브러리에 의존했습니다. Nuxt 2에서 마이그레이션하는 경우 마이그레이션 가이드를 참고하세요.
Nuxt는 상태 관리에 대해 특정한 의견을 갖고 있지 않으므로, 필요에 맞는 적절한 솔루션을 자유롭게 선택할 수 있습니다. 가장 인기 있는 상태 관리 라이브러리와의 다양한 통합이 제공됩니다: