[Nuxt] fetch 훅 사용시 주의점
출처 : https://nuxtjs.org/docs/concepts/nuxt-lifecycle#nuxt-lifecycle
- 주의점에 대해 설명하기에 앞서 라이프 사이클 먼저 알아보자.
nuxt
를 해본 사람이라면 잘 아는nuxt
라이프사이클 훅 흐름도이다.
✏️ SSR 동작시
1.nuxtServerInit
2.plugins
3.middleware
4.asyncData
5.beforeCreate
6.created
7.fetch
8.plugins
9.beforeCreate
10.created
11.beforeMount
12.mounted
✏️CSR 동작시
1.middleware
2.asyncData
3.beforeCreate
4.created
5.fetch
6.beforeMount
7.mounted
문제!!
async fetch(){
console.log('1. fetch start');
await this.dataFetching();
console.log('2. fetch end');
},
mounted(){
console.log('3. mounted');
},
methods:{
dataFetching(){
return new Promise((res,rej)=>{
setTimeout(()=>{
res();
},2000);
});
}
}
- Nuxt에서 위 코드를 실행하면 어떤 순서대로 콘솔에 찍힐까?
- 1 -> 2 -> 3 순서대로 호출이 된다고 생각했다면, 맞기도하고 틀리기도 하다.
- 위 문제는
SSR
로 동작하는지CSR
로 동작하는지에 따라 답이 다르다.
이유는?
다시 한번 흐름도를 살펴보자!
mounted
는 DOM이 렌더링되었을때 호출이 된다.
✏️SSR시 동작 순서
결과 먼저 보자면, 1 -> 2-> 3 순서로 실행이 된다.
fetch에 대한 설명
- SSR이나 CSR로 동작시 vue instance 가 생성이 된 이후 fetch훅이 실행이 된다. (그래서 Nuxt2.12 이후 vue instance 속성들에 접근이 가능함. )
- 페이지 렌더링은 fetch 훅까지 종료가 되고 서버에서 화면 구성을 마친 후 렌더링이 된다.(Nuxt는 fetch promise가 종료될 때까지 대기한다!!! )
- SSR시
$fetchState.pending
의 상태를 찍어 본다면 true로 나온다. CSR시엔 false가 나옴. - fetch는 캐싱을 지원해서 한 번 방문했던 곳에 저장이 가능 (feat. keep-alive)
- 렌더링의 진행 상태를 제공한다. →
$fetchState
- fetchState 코드 예시
위와 같이 상태에 따른 분기처리가 가능하다.<template> <div v-if="$fetchState.pending">Fetching 중 .... </div> <div v-else>Fetching 종료</div> </template> <script> export default{ async fetch(){ await ~~~~~~~ } } </script>
- fetchState 코드 예시
fetch 요약
- SSR로 동작시엔 fetch에 대한 라이프사이클 훅이 실행을 마칠때까지 10초가 걸리건 100초가 걸리건 상관 없이 유저 화면에 페이지가 렌더링이 되지 않을 것이다.(유저는 해당 페이지를 계속 못 보고 로딩되고 있는 화면만 보고있을 것이다.)
✏️CSR시 동작 순서
마찬가지로 결과 먼저 보자면, 1 -> 3 -> 2 로 실행이 된다.
- Nuxt 공식문서의 설명을 보면 이유를 알수있다.
- 첫 페이지 진입시엔 서버 측에서, 라우터로 이동할때는 클라이언트 측에서 fetch가 호출된다고 한다.
- 그렇다는건 CSR로 동작시에 fetch 훅이 비동기로 데이터를 가져오는 동안 DOM이 렌더링되었다면 mounted 훅이 동작을 하는 것이다.
- 위의 라이프 사이클 훅 흐름도를 다시 살펴보면 mounted() 후에 fetch complete가 되는걸 알 수 있다.
⭐️ 결론
- fetch는 asyncData에 비해 기능이 많고 모든 컴포넌트에서 사용이 가능해서 매력적인 훅이라고 생각한다.
- fetch에 대한 글들을 읽어보면 데이터를 스토어에 넣기위해서 사용한다는 글 들이 많다.
- 나는 컴포넌트 렌더링 이전에 비동기 로직을 호출 하는게 포인트라고 생각했지만, CSR시 컴포넌트가 렌더링이 된 후에도 데이터를 다 못 가지고 오는 경우도 있으므로 이 점은 잘 알아두고 사용해야 할 것 같다.
- 만약 무조건 mounted이후 완벽히 바인딩된 데이터를 보여줘야 한다면? SSR이나 CSR상관없이 똑같은 순서를 보장받고 싶고 비동기 로직을 호출을 해야 한다면,
asyncData
를 사용하면 된다.
asyncData
- 페이지 컴포넌트에만 제공되는 속성.
- 마치 뷰 라우터 네비게이션 가드에서 데이터를 호출하고 받아왔을 때 페이지를 진입하는 것과 같음.
- asyncData도 마찬가지로 promise가 처리될 때까지 기다린다
TMI : Fetch vs AsyncData?.
🚀 마지막 퀴즈
async asyncData(){
console.log('1. async start');
const data = await this.$axios.get('');
console.log('2. async end');
},
async fetch(){
console.log('3. fetch start');
const data = await this.$axios.get('');
console.log('4. fetch end');
},
mounted(){
console.log('5. mounted');
}
- 위 코드는 SSR과 CSR동작시 어떤 순서로 실행이 될까?
SSR
: 1(async start) → 2(async end) → 3 → 4 → 5
CSR
: 1(async start) → 2(async end) → 3 → 5 → 4
참고자료
🔗 Nuxt의 비동기 데이터 호출 방법
🔗 Nuxt공식 문서 Data Fetcing 설명
🔗 Nuxt Async Data 블로그 글
🔗 Between Asyncdata and Fetch in Nuxt
Author And Source
이 문제에 관하여([Nuxt] fetch 훅 사용시 주의점), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ssoon-m/Nuxt-fetch-훅-사용시-주의점저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)