Pinia - State에 Object type 정의

clean·2022년 6월 23일
0

State 에 Object type 정의하기

  • 처음에 Store에 Object Type을 정의하면서 실수가 있었다.

수정 전

Store

// store/search.ts
export const useSearchStore = defineStore('search', {
    state: (): SearchState => ({
      	// ...
        search: {}
      	// ...
    }),
    // ...
}

***.vue

<!--...-->
<v-col v-if="reportStore.search.type === 'A'">
  <!-- ... -->
<v-col>
//...

setup() {
	const reportStore = useReportStore();
  	watch(
      () => proxy.$route,
      (to: Route) => {
      	if (to.name==='targetPage') {
        	reportStore.search.type = 'A';
        }
      }
  	return {reportStore}
}
//...

위 코드의 문제점은 무엇일까?

  • 기본을 .. 간과했다는것,,,
  • Vue 는 속성의 추가/제거를 감지할 수 없다. 따라서 search.type 은 변경이 감지되지 않는다. (=reactive 하게 동작하지 않는다.)

    Vue는 반응형 속성을 동적으로 추가하는 것을 허용하지 않으므로, 빈 값을 사용하더라도 모든 루트 수준의 반응형 데이터 속성을 미리 선언하여 컴포넌트 인스턴스를 초기화해야 합니다.

수정 후

Store

// store/user.ts
export const useSearchStore = defineStore('search', {
    state: (): SearchState => ({
      	// ...
        search: {
        	// ...
          	type: 'DEFAULT',
          	// ...
        }
      	// ...
    }),
    // ...
});

vue component

<!--...-->
<v-col v-if="search.type === 'A'">
  <!-- ... -->
<v-col>
//...
setup() {
	const { search } = useReportStore();
  	watch(
      () => proxy.$route,
      (to: Route) => {
      	if (to.name==='targetPage') {
        	search.type = 'A';
        }
      }
  	return { search }
}
//...
  • 구조 분해 할당을 사용했다.
  • pinia 사용 시 store 로 부터 구조분해할당을 할 경우 반응성을 잃는데 Primitive Type 변수에만 해당되고, Reference Type 변수의 경우 주소값만 변경하지 않는 경우 반응성이 유지되는 것 같다.

문제점

computed나, storeToRefs 작업 없이 reactive 하게 변수가 동작하여 더 간편한데 Object Type 으로 정의하지 않을 이유가 있을까?

  • 객체가 reactive 하게 동작하게 하려면 초기 state 설정 시 객체를 미리 선언해야한다. 따라서 store.$reset() 호출 시 search 객체가 그대로 남아있다.
    • store.$reset() 호출 시 state에 미리 정의해둔 함수로 state를 초기화한다.
    • 객체의 크기가 작은 경우에는.. 상관없지만..... 데이터가 많은 경우에는.. 문제가 있지않나... 쩌업..
// 이렇게 선언해 둔 경우, 초기화 시 search 객체가 그대로 남아있다.
search: {
          // ...
          type: 'DEFAULT',
          // ...
       }

초기화 시 객체를 들고있지 않도록 아래와 같이 변경했다.

const defineSearchStore = defineStore('search', {
    state: (): SearchState => ({
      search: null
    }),
 	// ...
}
// searchStore 사용 시 search 객체 할당
export const useSearchStore = () => {
	const store = defineSearchStore();
  	store.search = { 
      		// ...
            type: 'DEFAULT',
          	//...
        }
  	return store;
}                                 

내용 정리

  • State 에 정의하지 않은 값들은 reactive하게 동작하지 않는다.
    - user:{}와 같이 정의 후 user.isAdmin = true 이렇게 나중에 정의하면 reactive하게 동작하지 않는다.
  • State 에 정의된 값으로 초기화 된다. (store.$reset() 호출 시)
  • reference type 의 state property 는 구조 분해 할당을 이용해도 reactive하게 동작한다. (재할당 하지 않는다면)

0개의 댓글