앞에서 카트 데이터를 뷰엑스 스토어에 담을 시 새로고침을 하면 스토어의 값이 사라지는 문제를 해결하기 위해 서버에 해당 데이터를 저장하고 이를 불러와서 스토어에 저장하는 방식을 사용하기로 했었다. 이 때 사용했던 방식이 cart 페이지 컴포넌트에서 asyncData로 스토어의 action을 dispatch하는 방식이었다. 아니면 아예 스토어 데이터를 nuxtServerInit 액션 속성을 이용해서 스토어가 생성될 때 미리 상태를 만들어두는 방식도 사용할 수 있었다. 하지만 만약 페이지 컴포넌트가 아닌 그냥 컴포넌트에서도 이렇게 서버사이드 단계에서 무언가 작업을 하고 싶다면?
asyncData는 페이지 컴포넌트에서만 활용이 가능하다. 만약 그냥 일반적인 컴포넌트에서도 서버사이드 측에서 데이터를 미리 불러와 사용하고 싶다면, fetch를 사용하면 된다.
asyncData의 단점은 페이지 컴포넌트가 아닌 일반 컴포넌트에서는 사용할 수 없다는 것이었다. 하지만 일반 컴포넌트에서도 서버 사이드 단계에서 미리 정해진 로직을 수행하고 싶을 때가 있을 것이다. 이 때 사용하는 것이 fetch이다.
<template>
...
</template>
<script>
import { FETCH_CART_ITEMS } from '@/store/index'
export default {
name: 'CartListView',
...
// async asyncData({ store }) {
// await store.dispatch(FETCH_CART_ITEMS)
// },
**async fetch() {
await this.$store.dispatch(FETCH_CART_ITEMS)
},**
}
</script>
<style scoped>
</style>
fetch가 호출되는 상황은 다음 두 가지의 상황이다. 이 둘의 상황에서 fetch가 호출되는 타이밍이 약간 다르다.
서버 사이드 렌더링을 위해 컴포넌트가 생성되고 나서 바로 실행
서버에서 해당 화면을 구성할 때 호출된다. 즉, 이미 화면에 데이터가 호출된 상태로 페이지가 호출된다.
브라우저에서 URL 주소를 변경해서 페이지를 이동할 때 실행
컴포넌트가 화면에 mounted 되고 나서 실행된다. 즉, 화면이 먼저 보이고 그 뒤에 데이터가 불려진다.
실제로 만약 fetch 안에 console.log(this)
라 찍고, 위의 두 상황을 생각해 보면 결과가 다르게 나온다.
외부에서 바로 들어갈 시 컴포넌트를 서버 사이드에서 생성한 다음 들어가기 때문에 NUXT SSR 콘솔이 찍히고, 다른 페이지에서 이동할 때는 이미 페이지가 만들어져 컴포넌트가 mount된 상황에서 this에 접근하기 때문에 그냥 VueComponent가 보여지는 것이다.
asyncData는 컴포넌트가 create되기 전에 호출이 되어, 미리 데이터를 서버사이드에서 불러올 수 있도록 하는 라이프사이클 훅이다. 이에 반해 fetch는 create()가 실행되어서 컴포넌트 인스턴스가 생성된 후에 불리게 된다. 따라서 asyncData는 this를 사용할 수 없지만 fetch에서는 this를 사용할 수 있다.