nuxt logo

문서 번역(비공식)

상태 관리

Nuxt는 강력한 상태 관리 라이브러리와 useState 컴포저블을 제공하여 반응적이고 SSR 친화적인 공유 상태를 생성합니다.

Nuxt는 컴포넌트 간에 반응적이고 SSR 친화적인 공유 상태를 생성하기 위해 useState 컴포저블을 제공합니다.

useState는 SSR 친화적인 ref 대체물입니다. 이 값은 서버 사이드 렌더링 후 (클라이언트 사이드 하이드레이션 동안) 보존되며, 고유한 키를 사용하여 모든 컴포넌트 간에 공유됩니다.

useState 내부의 데이터는 JSON으로 직렬화되므로, 클래스, 함수 또는 심볼과 같이 직렬화할 수 없는 것을 포함하지 않는 것이 중요합니다.

이것도 참고 api > composables > use-state

모범 사례

절대 <script setup> 또는 setup() 함수 외부에서 const state = ref()를 정의하지 마세요.
예를 들어, 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>
샘플 코드 편집 및 미리보기examples > features > state-management

전역적으로 캐시된 상태를 무효화하려면 clearNuxtState 유틸을 참조하세요.

상태 초기화

대부분의 경우, 비동기적으로 해결되는 데이터로 상태를 초기화하고 싶을 것입니다. 이를 위해 app.vue 컴포넌트와 callOnce 유틸을 사용할 수 있습니다.

app.vue
const websiteConfig = useState('config')

await callOnce(async () => {
  websiteConfig.value = await $fetch('https://my-cms.com/api/website-config')
})

이는 Nuxt 2의 nuxtServerInit 액션과 유사하며, 페이지 렌더링 전에 서버 사이드에서 스토어의 초기 상태를 채울 수 있습니다.

이것도 참고 api > utils > call-once

Pinia와의 사용

이 예제에서는 Pinia 모듈을 활용하여 전역 스토어를 생성하고 앱 전반에 걸쳐 사용합니다.

npx nuxt module add pinia를 사용하여 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
    }
  }
})

고급 사용법

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)))
}
샘플 코드 편집 및 미리보기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는 상태 관리에 대해 특정한 의견을 가지지 않으므로, 필요에 맞는 솔루션을 자유롭게 선택할 수 있습니다. 가장 인기 있는 상태 관리 라이브러리와의 여러 통합이 포함되어 있습니다:

  • Pinia - 공식 Vue 추천
  • Harlem - 불변 글로벌 상태 관리
  • XState - 상태 로직을 시각화하고 테스트할 수 있는 도구를 제공하는 상태 머신 접근법