Document를 통해 보는 Vue의 Composition API

Chaeil·2022년 6월 13일
1

Vue3를 사용하면서 Composition API와 Options API의 차이점이 궁금해졌다. Composition API는 Vue3에 새로 등장하였는데, 왜 등장하였는지, 기존의 Options API에 어떠한 문제점이 있었고, 어떻게 개선되었는지 알아보고 싶었고, 마침 Document에 설명이 나와있어서 Document를 읽고 정리한 것을 남기려 한다.


What is Composition API

Composition API는 다음 API들을 다루는 포괄적인 용어다.

  • Reactivity API, ref()reactive() 등 reactive state, computed state, watchers를 바로 생성할 수 있게 해준다.
  • Lifecycle Hooks, onMounted() , onUnomounted() 등, 컴포넌트 lifecycle에 프로그래밍 방식으로 연결할 수 있다
  • Dependency Injection, 다시 말해 provide()inject() 는 Reactivity API들을 사용하면서 Vue의 종속성 주입 시스템을 활용할 수 있다.

Vue3에서 주로 Single-File Components에서 <script setup> 과 같이 사용된다. 다음은 Composition API 사용의 예시이다.

<script setup>
import { ref, onMounted } from 'vue'

// reactive state
const count = ref(0)

// functions that mutate state and trigger updates
function increment() {
  count.value++
}

// lifecycle hooks
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

Why Composition API

Better Logic Reuse

Composition API의 장점은 Composable 형태로 클린하고 효율적인 로직을 재사용할 수 있다.

VueUse 같은 Composition Utilities들을 사용할 수 있다.

More Flexible Code Organization

Options API는 정해진 자리에 코드를 작성할 수 있는 장점이 있다. 하지만 로직의 복잡함이나 양이 커지면 단점이 생긴다. 가독성 저하, 로직이 나뉘는 점 등이 있다.

연관된 로직이 옵션에 따라 강제로 나뉘어 다른 부분에 위치하게된다. 즉 파일이 양이 커지면 스크롤을 위아래로 움직이면서 로직을 추적해야 하고 이것은 가독성 저하와 연결된다. 또한 이렇게 되면 재사용하기 위한 코드를 추출하는데도 번거로운 작업이 된다.

반면 Composition API로 작성한 경우 연관된 로직이 묶여서 한 곳에 있다. 더 이상 로직을 살펴볼 때 이동할 필요 없다. 또한 코드의 이동도 순조롭다. 즉 장기간으로 봤을 때 유지보수도 수월해진다.

Better Type Inference

Options API는 typescript 등장 이전에 등장했고 따라서 type 추론을 지원하기 위해 터무니 없이 복잡한 구조로 구현을 했지만 완벽히 지원하진 않았다.

따라서 이런 이유로 TS와 Vue를 같이 사용하려 했던 유저들은 class component로 코드를 작성하였다. class 방식은 Option API와 비슷한 문제점을 가진다.

이에 비해 Composition API 타입 추론이 원활하다.

Smaller Production Bundle and Less Overhead

Composition API와 <script setup> 으로 작성된 코드는 동일한 Options API보다 훨씬 효율적이고 최소한에 친화적이다.

<script setup> 컴포넌트에서 <script setup> 코드의 동일한 범위내에서 템플릿은 인라인된 함수로 컴파일된다.

this로 프로퍼티에 접근하는 것과 달리 컴파일된 템플릿 코드는 인스턴스 프록시 없이 <script setup> 에 선언된 변수에 바로 접근할 수 있다.


Relationship with Options API

Does Composition API cover all use cases?

stateful한 로직에 관해선 가능하다.

Can i use both APIs together?

가능하지만, 기존의 Options API로 작성된 코드가 있고 Composition API로 작성된 외부 라이브러리나 새로운 기능을 통합하는 경우 아니면 추천하지 않는다.

Will Options API be deprecated?

Options API도 Vue의 필수적인 부분이며, Composition API는 주로 큰 규모의 프로젝트에서 장점이 두드러지며, 그렇지 않은 프로젝트 경우 Options API도 충분한 대안이 된다.


Comparison with React Hooks

Composition API는 React Hook과 비슷한 역할을 하지만 약간의 차이가 있다.

React Hook은 컴포넌트가 업데이트 될 때마다 호출이 된다. 이것은 능숙한 React 개발자들에게도 혼란이 될 수 있다. 또한 심각한 성능 문제를 야기할 수 있다.

다음은 몇 가지 예이다.

  • Hooks은 호출 순서에 민감하며 조건적일 수 없다.
  • 리액트 컴포넌트에서 선언된 변수는 훅 클로저에 의해 캡처될 수 있으며 올바른 종속성 배열을 전달해주지 못하면 stale 될 수 있다. 따라서 리액트 개발자들은 ESLint 같은 도구에 의존하여 올바른 종속성 배열을 전달할 수 있도록 해야 한다. 하지만 이런 도구의 정확성은 보장할 수 없어서 과도한 종속성 배열을 요구할 수 있다.
  • 비용이 많이 드는 계산은 useMemo 를 사용해야 하며 종속성 배열에 수동적으로 전달해줘야 한다.
  • 불필요한 자식 컴포넌트까지 리렌더링이 되는 것을 막으려면 useCallback 같은 최적화 함수를 사용해야 하며 정확한 종속성 배열을 요구한다. 이를 무시하면 인지하지 못한채 심한 퍼포먼스 문제가 생길 수 있다.

이에 비해 Vue Composition API는 다음과 같다.

  • setup() 또는 <script setup> 코드를 한번만 호출한다. Composition API 호출도 호출 순서에 민감하지 않으며 조건부일 수 있다.
  • Vue의 reactivity system이 자동으로 의존하는 것들을 감지하기 때문에 종속성 배열 같은 것들을 직접 선언할 필요가 없다.
  • Child component나 캐시 콜백 함수 같은 최적화를 신경 쓸 필요가 없다.

마치며

글을 읽으면서 React의 Hook 등장배경과 Vue의 Composition API 등장배경이 상당히 유사하게 다가왔다. 최근에 React Hook 관련하여 document를 읽었는데 비슷하다고 느낀점은 다음과 같다.

  • 로직이 묶여 있기 때문에 클린하고 효율적으로 로직을 재사용할 수 있다.
  • 코드의 길이를 줄일 수 있다.
  • 로직의 관심사 분리
    • React의 클래스 컴포넌트 같은 경우 lifecycle method에 의해 로직이 분리됨. 따라서 연관된 로직은 나눠지고, 연관 없는 로직이 lifecycle method에 의해 묶이게 됨 → React Hook을 사용하여 연관 있는 로직을 작은 함수 안에 묶어놓음
    • Vue의 Options API 같은 경우 연관된 로직이 option에 따라 강제로 나뉘어 다른 부분에 위치하게 된다. → Composition API는 연관된 로직을 묶어 한 곳에 작성할 수 있다.

document를 통해 내가 궁금했던 부분을 명확히 알 수 있었고 추가로, React의 Hook과도 비교를 해줘서 흥미롭게 읽을 수 있었다. Hook과 비교를 읽으면서 꽤나 공감했던 부분은 React는 Hook을 사용할 때 dependency를 고려하며 개발하는 부분이 나름 까다로웠는데, 이 글을 읽고 생각해보니 Vue는 그러한 고민을 할 필요 없어서 꽤나 편리하게 개발한 거 같다.

profile
서글픈 너의 눈길은 나의 가슴을 아리게 한다

0개의 댓글