Prop drilling이란? | Vue

ian kwon·2024년 8월 8일

Vue.js에서 컴포넌트 기반의 구조를 사용하다 보면 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달해야 하는 경우가 많습니다. 이 과정에서 Prop Drilling이라는 문제가 발생할 수 있습니다. 이 글에서는 Prop Drilling이 무엇인지, 왜 발생하는지, 그리고 이를 피하는 방법에 대해 설명하겠습니다.

Prop Drilling이란?

Prop Drilling은 데이터가 여러 계층의 컴포넌트를 거쳐 최종적으로 필요한 컴포넌트에 도달하는 과정을 의미합니다. 부모 컴포넌트에서 시작해 자식, 손자, 증손자 컴포넌트로 연속적으로 props를 전달해야 할 때 발생합니다. 이는 코드의 가독성과 유지보수성을 떨어뜨릴 수 있습니다.

예시1 만약 1000개 이상의 계층이 있다면?? 벌써부터 어지럽다...

왜 Prop Drilling이 발생할까??

크게 3가지의 이유가 있습니다.

  1. 컴포넌트 계층이 깊을 때: 컴포넌트 계층이 깊어질수록 데이터를 전달하기 위해 거쳐야 하는 컴포넌트가 많아집니다.

  2. 전역 상태 관리 부재: 데이터를 중앙에서 관리하는 시스템이 없을 때, 필요한 데이터는 부모에서 자식으로 props를 통해 전달될 수밖에 없습니다.

  3. 재사용 가능한 컴포넌트 구조: 컴포넌트를 재사용하기 위해 일반화하다 보면, 데이터 전달이 여러 컴포넌트를 거쳐야 하는 상황이 생길 수 있습니다.

해결 방법은??

  1. Vuex 사용: Vuex는 Vue의 상태 관리 패턴 및 라이브러리로, 전역 상태를 중앙에서 관리할 수 있게 해줍니다. 이를 통해 직접적으로 props를 전달할 필요 없이 필요한 컴포넌트에서 전역 상태를 접근할 수 있습니다.

store.js

import { createStore } from 'vuex'

export default createStore({
  state: {
    message: 'Hello, Vuex!'
  },
  mutations: {
    setMessage(state, payload) {
      state.message = payload
    }
  }
})

ParentComponent.vue

<template>
  <child-component />
</template>

<script setup>
import { useStore } from 'vuex'

const store = useStore()
store.commit('setMessage', 'Updated message from ParentComponent')
</script>

ChildComponent.vue


<template>
  <div>{{ message }}</div>
</template>

<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'

const store = useStore()
const message = computed(() => store.state.message)
</script>
  1. Provide/Inject 사용: Vue 3에서는 provide/inject를 사용하여 조상 컴포넌트에서 후손 컴포넌트로 데이터를 전달할 수 있습니다.

ParentComponent.vue

<template>
  <child-component />
</template>

<script setup>
import { provide } from 'vue'

provide('message', 'Hello, Provide/Inject!')
</script>

GreatGrandChildComponent.vue

<template>
  <div>{{ message }}</div>
</template>

<script setup>
import { inject } from 'vue'

const message = inject('message')
</script>
  1. Composition API 사용: Vue 3에서는 Composition API를 사용하여 상태를 관리하고 전달할 수 있습니다. 이를 통해 보다 유연하게 상태를 공유할 수 있습니다.

useMessage.js

import { ref } from 'vue'

export function useMessage() {
  const message = ref('Hello, Composition API!')
  return {
    message
  }
}

AnyComponent.vue

<template>
  <div>{{ message }}</div>
</template>

<script setup>
import { useMessage } from './useMessage'

const { message } = useMessage()
</script>

vue3 이전에는 Event Bus로 prop drilling을 해결할 수 있었다..
Event Bus는 Vue 3에서는 공식적으로 지원되지 않습니다.

결론

Prop Drilling은 Vue.js 애플리케이션을 개발할 때 자주 마주하게 되는 문제 중 하나입니다. 그러나 Vuex, Provide/Inject, Event Bus, Composition API와 같은 다양한 방법을 통해 Prop Drilling을 효과적으로 피할 수 있습니다. 각 방법은 애플리케이션의 규모와 요구사항에 따라 적절하게 선택하여 사용하면 됩니다. 이를 통해 코드의 가독성과 유지보수성을 높일 수 있습니다.

profile
“당신이 두려워하는 일을 매일 하라.” -엘리너 루스벨트-

0개의 댓글