본문 바로가기

독후감

[실전 코드로 배우는 Vue.js] Chapter 6. 외부 데이터 통합

728x90
반응형

6.1 Axios란?

Http 요청을 처리하는 자바스크립트 오픈 소스 경량 라이브러리

fetch와 마찬가지로 프로미스 기반 HTTP 클라이언트이며, 서버(노드)와 브라우저에서 모두 사용할 수 있는 동질성 라이브러리

HTTP 요청을 가로채거나 최소할 수 있으며 사이트 간 요청 위조(CSRF) 방지 기능 내장

응답 데이터를 JSON 형식으로 자동 변환

6.2 Axios 설치

npm install axios

6.3 라이프사이클 훅과 Axios로 데이터 가져오기

created 또는 beforeMounted를 선택해야 하며, beforeMounted는 SSR에서 사용할 수 없으며 created 훅은 컴포지션 API에 대응하는 라이프사이클 함수가 없다.

가장 좋은 방법은 setup() 또는 <script setup>에서 반응형 컴포지션 함수로  외부 데이터를 가져오는 것

  • 프로미스 반환형
axios.get('https://api.github.com/users/mayashavin')
    .then(response => {
        user.value = response.data
    }).catch ((err) => {
        error.value = err as Error
    })
  • await/async 방식
async function getUser() {
    try {
        const response = await axios.get('https://api.github.com/users/mayashavin')
        user.value = response.data
    } catch (err) {
        error.value = err as Error
    }
}

컴포넌트의 라이프사이클은 동기식으로 진행되므로 Vue의 비동기 요청과 무관하게 컴포넌트 생성 작업을 계속 진행한다. 그래서 컴포넌트에서 서로 다른 데이터 요청을 처리하려면 특수한 조치가 필요하다(계속)

6.4 런타임 중 비동기 데이터 요청

컴포넌트 생성 프로세스가 끝나면 비동기 요청 실행 순서에 따라 해결/거부 결과를 차례로 처리

비동기 요청이 해결/거부되고 컴포넌트 데이터가 변경되면 Vue 렌더러가 컴포넌트 업데이트 프로세스 트리거

Vue가 DOM에 컴포넌트를 마운팅하는 시점은 아직 응답 데이터가 없기 때문에 컴포넌트의 로딩 상태를 관리해야 한다

컴포넌트 데이터에 loading프로퍼티를 추가하여 v-if로 로딩 상태관리 가능

6.5 재사용 fetch 컴포넌트 생성

<slot>을 이용해 loading 상태 및 data 관리

부모 컴포넌츠

    <FetchComponent url="https://api.github.com/users/mayashavin">
        <template #default="defaultProps">
            <div class="user-profile">
                <img :src="(defaultProps.data as User).avatar_url" alt="`${user.name} Avattar`" width="200" />
                <div>
                    <h1>{{ (defaultProps.data as User).name }}</h1>
                    <p>{{ (defaultProps.data as User).bio }}</p>
                    <p>Twitter: {{ (defaultProps.data as User).twitter_username }}</p>
                    <p>Blog: {{ (defaultProps.data as User).blog }}</p>
                </div>
            </div>
        </template>
    </FetchComponent>

자식 컴포넌츠

<template>
    <slot name="loading" v-if="loading">
        <div class="loading-message">Loading...</div>
    </slot>
    <slot :data="data" v-if="data">
    </slot>
    <slot name="error" :error="error" v-if="error">
        <div class="error">
            <p>Error: {{ error.message }}</p>
        </div>
    </slot>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import axios from 'axios';

const data = ref<object | undefined>();
const error = ref<Error | undefined>();
const loading = ref<boolean>(false);

const props = defineProps({
    url: {
        type: String,
        required: true,
    },
    method: {
        type: String,
        default: "GET",
    }
})

async function fetchData () {
    try {
        loading.value = true;
        const response = await axios(props.url, {
            method: props.method,
            headers: {
                'Content-Type' : 'application/json',
            }
        })
        data.value = response.data
    } catch (err) {
        error.value = err as Error
    } finally {
        loading.value = false;
    }
}

fetchData();
</script>

6.6 애플리케이션과 외부 데이터베이스 연결

Vue가 컴포넌트를 생성할 때마다 데이터를 가져오는 방식은 최선이 아니다. 특히 컴포넌트의 데이터가 자주 변경되지 않는 경우라면 더욱 그렇다.

페이지 데이터는 뷰를 처음 로드할 때 한 번만 가져와야 한다. 브라우저 로컬 저장소를 외부 데이터베이스로 삼거나 Vuex, 피니아 등 상태 관리 서비스로 데이터를 캐시에 저장해야 한다.

-LoccalStorage 사용 예시-

localStorage는 브라우저가 사설/익명 세션의 localStorage를 매번 초기화하고 사용자 또한 기능을 끌 수 있기 때문에 피니아 등의 상태 관리 도구를 사용하는 것이 좋다.

Nuxt3에서 useFetch 사용

 

 

useFetch · Nuxt Composables

Fetch data from an API endpoint with an SSR-friendly composable.

nuxt.com

useFetch

사용 이유

  • 리액티브 데이터 관리 : 데이터를 가져온 결과를 리액티브 데이터로 반환하여 반응형으로 활용 가능
  • SSR 지원 : 서버에서 데이터를 가져올 때 자동으로 SSR과 통합. SSR 환경에서 요청 결과를 HTML에 포함하고, 클라이언트에서 이를 하이드레이션
  • 자동 캐싱 : 같은 요청이 여러 번 발생하면 캐싱된 데이터 반환

$fetch를 SSR에서 사용하면 두번 호출되는 이유

  • 서버사이드 렌더링(SSR)과 클라이언트 하이드레이션(hydration) 과정이 각각 실행
  • 서버에서 렌더링된 HTML에는 데이터가 포함되어 있지만, 클라이언트는 이를 상태(state)로 자동으로 복원하지 않음
  • 클라이언트가 자체적으로 데이터를 요청해 상태를 초기화하려 하기 때문에 $fetch와 같은 함수가 다시 호출

하이드레이션

  • 서버에서 렌더링된 HTML을 클라이언트에서 동적으로 활성화(reactivate)하는 과정.
  • 서버에서는 초기 페이지를 렌더링하고, 클라이언트는 그 페이지를 받아서 JavaScript로 실행 가능한 상태로 만듬(활성화)
  • Vue와 Nuxt가 클라이언트 측에서 상태를 동기화 하려 하기 때문에 함수가 다시 호출될 수 있음.

useAsyncData

  • SSR 단계에서 데이터를 가져오고, 클라이언트로 전달된 HTML에 데이터를 JSON으로 직렬화하여 포함시킴
  • 클라이언트는 서버에 전달된 데이터를 직렬화된 상태로 읽어와 하이드레이션하여 데이터가 재호출되지 않음
  • useAsyncData를 사용하지 않으면 클라이언트는 자신의 초기 상태를 알 수 없으므로, 데이터를 다시 요청 보냄
  • useFetch는 useAsyncData와 $fetch를 함께 사용하는 기능을 제공(페이지 파라미터 변경 탐지 등과 같은 차이는 있음)

 

728x90
반응형