HOC | high order component | Component recycling
2024. 1. 31. 14:29ㆍStudy/Vue
HOC (high order component)
뷰의 하이 오더 컴포넌트는 리액트의 하이 오더 컴포넌트에서 기원된 것입니다. 리액트의 하이 오더 컴포넌트 소개 페이지를 보면 아래와 같이 정확한 정의가 나와 있습니다. A higher-order component (HOC) is an advanced technique iin React for reusing component logic. 이 말을 정리해보면 다음과 같습니다.
하이 오더 컴포넌트는 컴포넌트의 로직(코드)을 재사용하기 위한 고급 기술입니다.
반복되는 컴포넌트 로직
여기서 커포넌트 로직을 재사용한다는 말은 무슨 의미일까요? 이 표현에서 가리키고 있는 컴포넌트 로직이란 뷰에서 인스턴스 옵션을 의미합니다. 컴포넌트 들에서 공통적으로 들어가는 인스턴스 옵션이 있을 때 반복되는 코드를 줄여줄 수 있습니다.
1. high order component 정의
src/views/CreateListView.js
import EventBus from '../utils/EventBus.js'
import ListView from '../components/ListView.vue';
// high order component
export default function createListView(componentName){
return {
// 재사용 할 인스턴스(컴포넌트) 옵션들이 들어갈 자리
name: componentName,
mounted() {
EventBus.$emit('off:loading');
this.$store.dispatch('FETCH_LIST', this.$route.name)
.then( () => EventBus.$emit('end:spinner')
.catch( e => console.log(e) );
},
// render() 함수로 컴포넌트를 로딩한다.
render(createComponent) {
return createComponent(ListView);
}
}
}
위 코드는 CreateListComponent라는 하이 오더 컴포넌트를 구현한 코드입니다.
하이 오더 컴포넌트를 적용한 컴포넌트들의 공통 코드들(mounted, name 등)을 미리 정의합니다.
그리고 이 하이 오더 컴포넌트를 router 파일에서 사용합니다.
2. router에서 HOC 연결
src/router/index.js
import createListView from '../views/createListView.js'; // HOC
new VueRouter({
routes: [
{
path: '/news',
component: createListView('NewsView')
},
{
path: '/ask',
component: createListView('AskView')
},
// ...
]
})
위와 같은 방식으로 하이 오더 컴포넌트를 router에서 임포트 하고, 각 컴포넌트의 이름만 정의를 해주면 컴포넌트의 기본 공용 로직인 mounted(), name을 가진 컴포넌트가 생성됩니다. 따라서, 컴포넌트마다 불 필요하게 반복되는 코드를 정의 하지 않아도 됩니다.
src/views/ListView.vue
<template>
<div>
<list-item></list-item>
</div>
</template>
<script>
import ListItem from '../components/ListItem.vue';
export default {
components: {
ListItem,
}
}
</script>
src/components/ListItem.vue
<template>
<ul class="item_list">
<li v-for="(item, i) in list" :key="i" :id="item.id">
<template v-if="item.points">
<div class="points">
{{ item.points }}
<small>points</small>
</div>
</template>
<div class="ttl_wrap">
<strong>
<template v-if="$route.name !== 'ask'">
<a :href="item.url" target="blank">{{ item.title }}</a>
</template>
<template v-else>
<router-link :to="`/item/${item.id}`">{{ item.title }}</router-link>
</template>
</strong>
<p class="info_txt">
<span v-if=" item.type === 'job' " class="domain"><a :href="`http://${item.domain}`" target="blank">{{ item.domain }}</a></span>
<span v-if="item.user"><router-link :to="`/user/${item.user}`"><i class="fa-solid fa-user"></i> {{ item.user }}</router-link></span>
<span>{{ item.time_ago }}</span>
<span>{{ item.comments_count }} comments</span>
</p>
</div>
</li>
</ul>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
computed: {
...mapGetters(['list']),
},
}
</script>
view devtools로 확인해보면 JobsView 라는 HOC가 생성된 것을 확인할 수 있다.
HOC (하이 오더 컴포넌트)의 단점
- 일반: 상위 - 하위
- HOC: 상위 - HOC - 하위
HOC를 이용하여 컴포넌트를 컴포넌트를 개발해 나가는 경우, 상위와 하위 컴포넌트 로직은 변경하지 않은 채 기능을 확장해 나갈 수 있습니다. 하지만 컴포넌트의 레벨이 깊어지고, 그로 인해 컴포넌트 간 통신이 불편해는 단점이 있습니다.
캡틴판교 | Cracking Vue.js | High Order Components
https://joshua1988.github.io/vue-camp/design/pattern5.html
'Study > Vue' 카테고리의 다른 글
Navigation Guard (0) | 2024.01.31 |
---|---|
mixin | Component recycling (0) | 2024.01.31 |
Vuex, 헬퍼, 모듈화 (0) | 2024.01.25 |
Composition API follower 검색기능 (0) | 2023.10.04 |
Composition API (0) | 2023.10.04 |