Vue - Vue State Management

jun_grammer·2024년 5월 9일

Vue.js

목록 보기
5/5
post-thumbnail

State Management

개요

State Management

상태 관리

Vue 컴포넌트는 이미 반응형 상태를 관리하고 있음

-> 상태 === 데이터

컴포넌트 구조의 단순화

  • 상태(State)
    • 앱 구동에 필요한 기본 데이터
  • 뷰(View)
    • 상태를 선언적으로 매핑하여 시각화
  • 기능(Actions)
    • 뷰에서 사용자 입력에 대해 반응적으로 상태를 변경할 수 있게 동작

-> "단방향 데이터 흐름"의 간단한 표현

상태 관리의 단순성이 무너지는 시점

  • "여러 컴포넌트가 상태를 공유할 때"
    1. 여러 뷰가 동일한 상태에 종속되는 경우
    2. 서로 다른 뷰의 기능이 동일한 상태를 변경시켜야 하는 경우
  1. 여러 뷰가 동일한 상태에 종속되는 경우
    • 공유 상태를 공통 조상 컴포넌트로 "끌어올린" 다음 props로 전달하는 것
    • 하지만 계층 구조가 깊어질 경우 비효율적, 관리가 어려워 짐

  1. 서로 다른 뷰의 기능이 동일한 상태를 변경시켜야 하는 경우
    • 발신(emit)된 이벤트를 통해 상태의 여러 복사본을 변경 및 동기화 하는 것
    • 마찬가지로 관리의 패턴이 깨지기 쉽고 유지 관리할 수 없는 코드가 됨

해결책

  • 각 컴포넌트의 공유 상태를 추출하여, 전역에서 참조할 수 있는 저장소에서 관리

  • 컴포넌트 트리는 하나의 큰 view가 되고 모든 컴포넌트는 트리 계층 구조에 관계 없이 상태에 접근하거나 기능을 사용할 수 있음

-> Vue의 공식 상태 관리 라이브러리 === "Pinia"

State management library(Pinia)

Pinia

Pinia

Vue 공식 상태 관리 라이브러리

Pinia 설치

  • Vue 프로젝트 빌드 시 Pinia 라이브러리 추가

Vue 프로젝트 구조 변화

  • stores 폴더 신규 생성

Pinia 구조

Pinia 구성 요소

  1. store
  2. state
  3. getters
  4. actions
  5. plugin
// stores/counter.js

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

/*
1. store

- 중앙 저장소
- 모든 컴포넌트가 공유하는 상태, 기능 등이 작성됨

-> defineStore()의 반환 값의 이름은 use의 store를 사용하는 것을 권장
-> defineStore()의 첫번째 인자는 애플리케이션 전체에 걸쳐 사용하는 store의 고유 ID
*/
export const useCounterStore = defineStore('counter', () => {

/*
2. state

- 반응형 상태(데이터)
- ref() === state
*/
  const count = ref(0)

/*
3. getters

- 계산된 값
- computed() === getters
*/
  const doubleCount = computed(() => count.value * 2)

/*
4. actions

- 메서드
- function() === actions
*/
  function increment() {
    count.value++
  }

/*
Setup Stores의 반환 값

- Pinia의 상태들을 사용하려면 반드시 반환해야 함

※ store에서는 공유 하지 않는 private한 상태 속성을 가지지 않음
*/
  return { count, doubleCount, increment }
})

/*
5. plugin

- 애플리케이션의 상태 관리에 필요한 추가 기능을 제공하거나 
  확장하는 도구나 모듈
- 애플리케이션의 상태 관리를 더욱 간편하고 유연하게 만들어주며 
  패키지 매니저로 설치 이후 별도 설정을 통해 추가 됨
*/

Pinia 구성 요소 정리

  • Pinia는 store라는 저장소를 가짐
  • store는 state, getters, actions으로 이루어지며
    각각 ref(), computed(), function()과 동일함

Pinia 구성 요소 활용

State

  • 각 컴포넌트 깊이에 관계 없이 store 인스턴스로 state에 접근하여 직접 읽고 쓸 수 있음
  • 만약 store에 state를 정의하지 않았다면 컴포넌트에서 새로 추가할 수 없음
<!-- App.vue -->

<template>
  <div>
    <p>state : {{ store.count }}</p>
  </div>
</template>

<script setup>
import { useCounterStore } from './stores/counter';

const store = useCounterStore()

// state 참조 및 변경
console.log(store.count)
const newNumber = store.count + 1
</script>

Getters

  • store의 모든 getters 또한 state 처럼 직접 접근 할 수 있음
<!-- App.vue -->

<template>
  <div>
    <p>getters : {{ store.doubleCount }}</p>
  </div>
</template>

<script setup>
console.log(store.doubleCount)
</script>

Actions

  • store의 모든 action 또한 직접 접근 및 호출 할 수 있음
  • getters와 달리 state조작, 비동기, API 호출이나 다른 로직을 진행할 수 있음
<!-- App.vue -->

<template>
  <div>
	<button @click="store.increment()">+++</button>
  </div>
</template>

<script setup>
// actions 호출
store.increment()
</script>
profile
게임개발자가 되는 그날까지

0개의 댓글