FrontEND/vue

Pinia 상태 모듈화 – 도메인 별로 관리하는 효율적인 상태 구조 만들기

mingmingIT 2025. 4. 25. 10:07

프로젝트가 커질수록 하나의 store 파일에 모든 상태를 넣는 건 유지보수의 지옥입니다.
이럴 때 필요한 것이 바로 모듈화입니다. Pinia는 기본적으로 store 파일을 개별 모듈처럼 분리해서 사용할 수 있게 설계되어 있어 매우 간단하게 적용할 수 있습니다.


1. 모듈화 폴더 구조 예시

 
src/
├── stores/
│   ├── index.js (선택)
│   ├── userStore.js
│   ├── postStore.js
│   └── commentStore.js

2. 개별 store 모듈 정의하기

예시: userStore.js

// src/stores/userStore.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    user: null,
    isLogin: false
  }),
  actions: {
    login(userData) {
      this.user = userData
      this.isLogin = true
    },
    logout() {
      this.user = null
      this.isLogin = false
    }
  }
})

예시: postStore.js

// src/stores/postStore.js
import { defineStore } from 'pinia'
import axios from '@/api/axiosInstance'

export const usePostStore = defineStore('post', {
  state: () => ({
    posts: [],
    loading: false
  }),
  actions: {
    async fetchPosts() {
      this.loading = true
      const { data } = await axios.get('/posts')
      this.posts = data
      this.loading = false
    }
  }
})

3. 컴포넌트에서 여러 store 사용하기

컴포넌트에서 필요한 store만 골라서 사용할 수 있습니다.

<script setup>
import { useUserStore } from '@/stores/userStore'
import { usePostStore } from '@/stores/postStore'

const userStore = useUserStore()
const postStore = usePostStore()
</script>

<template>
  <div>
    <h1>안녕하세요, {{ userStore.user?.name || '게스트' }}님!</h1>
    <button @click="postStore.fetchPosts">게시글 불러오기</button>

    <ul>
      <li v-for="post in postStore.posts" :key="post.id">{{ post.title }}</li>
    </ul>
  </div>
</template>

4. 모듈화의 이점

항목 설명
도메인별 분리 user, post, comment 등 독립적인 상태 관리 가능
재사용성 ↑ 필요한 store만 가져다 쓰면 됨
유지보수 용이 버그 추적 및 디버깅 시 store 범위가 명확함
타입 지원 강화 TypeScript 환경에서 명확한 타입 지정 가능

5. 선택사항: store들을 한 번에 불러오는 index.js 만들기

// src/stores/index.js
export * from './userStore'
export * from './postStore'
export * from './commentStore'

이렇게 하면 컴포넌트에서 store를 불러올 때 다음처럼 간단히 사용 가능:

import { useUserStore, usePostStore } from '@/stores'

마무리

Pinia는 Vuex보다 훨씬 유연하게 설계되어 있어, 모듈화를 직접 구성하는 데에 별도 설정이 필요 없습니다.
단순히 store 파일을 여러 개로 나누는 것만으로도 자연스럽게 모듈화가 이루어지고,
컴포넌트에서는 필요한 store만 호출해서 사용하면 되는 구조입니다.

복잡한 대형 프로젝트로 갈수록 이런 구조는 필수입니다. 글을 마치겠습니다.