안녕하세요 한 달 만에 블로그글에 글을 쓰네요
최근 개발을 React로 주로 하다 보니 vue에 대한 관심이 많이 떨어져서 새로운 상태 관리 라이브러리가 나온 지도 모르고 있었네요
그래서 이번에는 vue3의 새로운 상태 관리 라이브러리인 Pinia에 대해 알아보도록 하겠습니다
Pinia는 무엇인가?
pinia는 vue의 상태 관리 라이브러리 중 하나이며 vue3 버전을 고려하여 설계된 최신 상태 관리 라이브러리입니다
기존에 많이 사용하던 vuex와 유사하지만 Compostion API를 통한 유연한 사용과 향상된 TypeScript 지원으로 더 간편하고 직관적인 상태 관리를 할 수 있습니다
Vuex와 Pinia의 차의 점
vuex와 pinia 모두 vue의 상태 관리 라이브러리입니다
vuex는 vue의 공식적인 상태 관리 라이브러리이며 상태관리가 안정적입니다. 다만 상태 관리가 조금 복잡하고 타입스크립트에 대한 지원이 완벽하게 되어있지는 않습니다
이러한 단점을 보완하고자 Pinia가 등장하였습니다. Pinia는 vue3의 Compostion API를 기반으로 설계된 상태 관리 라이브러리입니다
직관적인 API와 완벽하게 타입스크립트를 지원합니다. 또한 기존 vuex는 mutation를 통해 상태를 변경해야 했었는데 Pinia는 mutation 없이 상태를 직접 변경할 수 있습니다
리액트에 비유하자면 리액트에서는 대표적인 상태 관리 라이브러리인 redux가 있습니다. 그러나 redux의 단점을 보완하고자 최근 recoil과 같은 다양한 상태 관리 라이브러리가 등장한 것과 비슷합니다
pinia는 vuex의 단점을 보완하기 위해 등장한 상태 관리 라이브러리입니다. 그러나 vuex가 일반적으로 상태 관리가 안 좋다는 의미는 아닙니다 프로젝트의 필요성에 따라 더 직관적인 API와 향상된 Typescript 지원이 필요하면 Pinia, 안정적이고 검증된 상태 관리 라이브러리를 원한다면 vuex를 선택할 수 있습니다
이제 Pinia에 대해 더 자세히 알아보도록 하겠습니다
Pinia의 주요 구성 요소
defineStore
Pinia에서 상태 저장소를 정의하는 데 사용되는 함수입니다
이 함수는 상태(state), 액션(actions), 게터(getters)를 정의하는 객체를 인자로 받습니다.
defineStore 함수를 사용하여 상태 관리 로직을 포함하는 저장소를 생성할 수 있습니다
state
state는 저장소의 상태를 정의하는 객체입니다. Pinia에서는 이 상태를 직접 변경하는 것이 가능합니다
이러한 state의 변경은 pinia에 의해서 자동으로 추적이 되고 변경사항이 반응적으로 업데이트됩니다
actions
비동기 작업을 포함한 상태 변경을 처리하는 메소드 입니다
pinia에서는 mutation 없이 직접 상태를 변경하는 것이 가능합니다.
액션은 api 호출과 같은 비동기 작업을 수행하거나, 다른 액션을 호출하는 등에 복잡한 작업을 캡슐화할 수 있습니다
getters
저장소의 상태를 기반으로 계산된 값을 제공하는 메소드 입니다
vuex의 getters와 유사하여 getters는 저장소의 상태를 가져와 사용할 때 중복 코드를 줄이고 코드의 가독성을 향상합니다
Composition API 기반 Pinia
Pinia SetUp
우선 Pinia를 프로젝트에 설치하도록 하겠습니다
yarn add pinia
이후 vue 프로젝트 파일 중 main.ts 파일을 아래와 같이 수정합니다
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import { createPinia } from "pinia";
const pinia = createPinia();
createApp(App).use(router).use(pinia).mount("#app");
상태 정의
defineStore 함수를 사용하여 저장소를 생성합니다
defineStore는 저장소의 고유한 키 값과 state, actions, getters의 구조로 되어있습니다
compostion api 기반으로 상태를 관리할 경우 아래와 같이 설정할 수 있습니다
ref를 통해 state를 정의하고, computed로 getters를 정의합니다
그리고 function을 사용해서 actions를 정의해 주면 됩니다
export const useCounterState = defineStore("counter", () => {
const count = ref<number>(0);
const doubleCounter = computed(() => count.value * 2);
function increment() {
count.value++;
}
return { count, doubleCounter, increment };
});
상태 사용
정의한 상태를 컴포넌트에서 사용해 보도록 하겠습니다
컴포넌트에서는 정의한 상태를 import 하여 사용할 수 있습니다
export default defineComponent({
name: "HomeView",
setup() {
const counterState = useCounterState();
const { count, doubleCounter } = storeToRefs(counterState);
return { count, counterState, doubleCounter };
},
});
그러나 이때 일반적인 구조 분해 할당을 통해 상태의 객체들을 가져오게 되면 상태가 반응형으로 작동하지 않게 됩니다
즉 상태가 업데이트되더라도 이 변경사항이 컴포넌트에 반영이 되지 않습니다
이러한 문제를 해결하기 위해 Pinia에서 storeToRefs라는 함수를 제공해 줍니다
이 함수를 통해 상태를 가져오고 그 후 구조 분해 할당을 하게 되면 상태는 반응형으로 동작하게 됩니다
storeToRefs를 사용하면 상태가 업데이트가 되면 즉시 컴포넌트에 반영이 되어 동적인 사용자 경험을 제공할 수 있습니다
로컬스토리지 저장
기존 vuex에서는 vuex-persistedstate와 같은 라이브러리를 통해 상태를 스토리지에 저장하였습니다
Pinia도 마찬가지로 pinia-plugin-persist 라이브러리를 통해 상태를 스토리지에 저장할 수 있습니다
우선 아래 명령어로 라이브러리를 설치하겠습니다
yarn add pinia-plugin-persist
이후 vue main.ts 파일을 아래와 같이 수정합니다
pinia에 piniaPersist를 추가해 주는 과정입니다
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import { createPinia } from "pinia";
import piniaPersist from "pinia-plugin-persist";
const pinia = createPinia();
pinia.use(piniaPersist);
createApp(App).use(router).use(pinia).mount("#app");
다음으로 아까 정의했던 definedStore에 persist 옵션을 추가해 주면 definedStore 키 값으로 로컬스토리지에 저장이 됩니다
export const useCounterState = defineStore(
"counter",
() => {
const count = ref<number>(0);
const doubleCounter = computed(() => count.value * 2);
function increment() {
count.value++;
}
return { count, doubleCounter, increment };
},
{
persist: {
enabled: true,
strategies: [{ storage: localStorage }],
},
}
);
여기까지 Vue에 새로운 상태 관리 라이브러리인 Pinia에 대해 알아보았습니다
마치며
개인적으로 react에서 redux를 쓰다가 recoil를 사용하는 느낌이 들었습니다
불필요한 보일러 플레이트 코드를 작성하지 않아도 되고 Vue3와 잘 맞아 직관적인 코드를 작성할 수 있는 거 같습니다
아직 조금 더 사용해 봐야 되긴 할 거 같지만 저는 만약 새로운 vue 프로젝트를 한다면 pinia를 사용해서 상태 관리를 진행할 거 같습니다
'vue.js' 카테고리의 다른 글
Vuetify + Socket Io 를 사용하여 채팅 웹 사이트 만들기-2 (0) | 2022.06.19 |
---|---|
Vuetify + Socket Io 를 사용하여 채팅 웹 사이트 만들기-2 (0) | 2022.06.10 |
Vuetify + Socket Io 를 사용하여 채팅 웹 사이트 만들기-1 (0) | 2022.06.05 |
Vue Cli 설치 및 프로젝트 세팅 (0) | 2021.12.12 |