📌최근 발생한 문제점 $ref undefined
mounted()에서 $ref에 접근을 해서 무언가를 적용을 하려고 해 봤는데,
$ref에 접근이 안되고 undefined가 뜨는 오류가 발생했다.
무엇이 문제인지 찾아본 결과
<client-only>안에 있는 $ref에 접근을 할 때,
초반에 undefined가 발생할 수 있다는 점을 찾아냈다.
이러한 상황은 왜 발생하는걸까?
먼저 이 문제를 알기 위해서는 <client-only>를 왜 사용하는지를 알아야 했고,
SSR과 CSR의 차이를 먼저 이해해야 되어서
오늘은 이 부분을 정리해보기로 했다!
⚙️SSR이란?
Server Side Rendering이라고 해서
Server에서 렌더링이 된 HTML 화면을 만들어서 보내주는 방식을 말한다.
SSR로 처리가 된다고 하면 모든 리소스를 서버에서 랜더링 한 다음에
클라이언트 쪽에 Return을 해주기 때문에 페이지를 모두 구성하는데 서버 측에 부담이 있으나
받기만 한다면 바로 완성된 화면을 띄울 수 있어 초기 로딩 속도가 빠르다.
🧾CSR이란?
SSR과 반대되는 경우가 CSR(Client Side Rendering)이 있다.
Client Side Rendering이라고 해서
서버에서 HTML과 Javascipt를 함께 보내서
클라이언트에서 두 파일을 받아 같이 랜더링을 하는 것을 말한다.
CSR의 경우 일단 페이지가 뜨나, 처음 빈 페이지가 뜨고,
그다음에 화면을 그릴 자바스크립트와 HTML 읽어 Rendering 실행하기 때문에
SSR보다 초기 로딩 시간은 더 오래 걸린다.
🎁vue + Nuxt.js
Vue에서 SSR처리를 위한 프레임워크는 바로 nuxt.js이다.
나의 경우도 Nuxt를 이용해서 프로젝트를 구성을 많이 하고 있다.
하지만, SSR를 구현을 했지만 필요에 따라서 CSR이 필요한 부분들이 있었다.
이럴 때 이용하는 것이 바로 <client-only> 컴포넌트였다.
<client-only>
<client-only> 컴포넌트 안에 들어있는 자식 요소들은 클라이언트 사이드 랜더링을 진행하게 된다.
<template>
<div>
<sidebar />
<client-only placeholder="Loading...">
<!-- this component will only be rendered on client-side -->
<comments />
</client-only>
</div>
</template>
위의 예시를 보면 client-only안에 있는 comments는 CSR로 호출을 할 수 있고
Client Side에서 그려지는 동안 Placeholder에 작성된 텍스트가 표시되게 됩니다.
<no-ssr>
Nuxt.js v2.9.0 버전 전에는 <no-ssr>를 사용했으나,
위 버전 이상부터는 <client-only>로 변경되었으니,
최신 버전에서는 <client-only>를 사용하면 된다.
🥲<client-only> 안의 $ref 문제
<client-only> 안에서 $ref가 있어서 해당 요소에 접근을 하려다 보면은
바로 접근이 되지 않은 채 undefined가 뜨는 경우가 있다.
이런 경우는 Client에서 Rendering을 해주기 때문에 mounted가 되더라도
아직 그려지지 않았다면 해당 컴포넌트를 아직 읽을 수 없는 상황인 것이다.
Nuxt에서는 $netTick을 이용해서 준비가 될 때를 체크해서 접근을 하는 아래 코드를 제시하고 있다.
mounted(){
this.initClientOnlyComp()
},
methods: {
initClientOnlyComp(count = 10) {
this.$nextTick(() => {
if (this.$refs.myComp) {
//...
} else if (count > 0) {
this.initClientOnlyComp(count - 1);
}
});
},
}
mounted 시 initClientOnlyComp를 호출해서
this.$ref가 있는지 없는지를 체크한 뒤 만약 없다면 다시 해당 function을 재호출 한다.
초기 count횟수만큼 해당 function을 재 호출한다.
관련 포스팅
https://ordinary-code.tistory.com/147
Reference
https://nuxtjs.org/docs/features/nuxt-components/
https://www.toptal.com/vue-js/server-side-rendered-vue-js-using-nuxt-js
'FrontEnd > Vue.js' 카테고리의 다른 글
[Nuxt]다음 카카오 우편번호 서비스 Vue 프로젝트에 연동하기 (1) | 2022.07.05 |
---|---|
[javascript/Vue] dayjs에서 요일 한국어 적용하기 (locale/ko) (0) | 2022.05.03 |
[Vue.js/Nuxt] vue-masonry-css를 이용해서 카드레이아웃 구현하기 (0) | 2022.04.30 |
[vue.js] image 없을 경우 default 이미지 처리하는 방법 @error 사용하기 (0) | 2022.04.26 |
[Vue.js] ref undefined일 경우 해결 방법 (this.$nextTick) (0) | 2022.03.22 |