Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

짱이 될거야

Vuex에서 api 요청 느릴 경우 페이지 렌더링 해결 편법 본문

프로젝트

Vuex에서 api 요청 느릴 경우 페이지 렌더링 해결 편법

jeong57 2022. 9. 28. 21:35

현재 진행하고 있는 프로젝트에서 프론트는  Vuex를, 백엔드는 JPA를 사용하고 있다.

프론트에서 백으로 API 요청을 보내면 몇 백개의 데이터를 정제해서 돌려주는 경우가 있는데, 이때 요청 후 결과를 받기까지 약 0.5초 가량이 걸린다.

이것 때문에 페이지 렌더링에서 문제가 발생하는데, 자주 언급했던 것처럼 결과가 오기 전에 페이지가 렌더링 되어버리기 때문에 화면에 제대로 된 데이터를 보여주지 못한다.

updated 시점에서 axios 요청을 한 번 더 한다 하더라도 이미 결과 데이터가 오기 전에 존재하던 데이터를 화면에 띄워버렸기 때문에 화면 데이터는 실시간으로 바뀌지 않는다.

 

 

결과적으로 해결할 수 있는 방법은 딱 하나이다.

바로, 결과 데이터가 오고 나서 데이터를 띄우는 것이고 vuex에서는 보통 v-if 문을 사용한다.

 

 

오늘 또 이러한 에러를 만났고 해결 과정은 다음과 같다.

기존 코드는 store의 state에서 빈 데이터(a라고 하자)를 하나 만들고, getters에서 해당 데이터를 저장하고, actions에서 axios를 요청하면 그 데이터에 결과값을 넣는 구조로 구성되어 있었다.

컴포넌트의 created() 시점에서 해당 action을 호출하고 그 다음에 (아마도 결괏값이 저장되어 있을) getters 데이터(a)를 가져오는 것을 async await을 써서 비동기식으로 구현했다. 그리고 데이터 a가 있다면 하위 컴포넌트를 불러오기로 했는데, 여기서 문제는 v-if가 항상 참이 돼서 하위 컴포넌트가 열렸다는 것이다.

데이터 a는 state에 있는 값이기 때문인지 몰라도 null 값일 때가 없었다. 따라서 axios 결괏값이 데이터 a에 저장되던 되지 않던 항상 v-if 문이 참이 돼서 하위 컴포넌트가 열렸고, 결과적으로 axios로 받아와야 하는 결과값은 화면에 뜨지 않았다.

 

 

1. 편법: setTimeout()

해결 방법을 찾다가 너무 안돼서 편법을 쓰기로 했다.

바로 setTimeout()이다.

아래와 같은 코드는 5000ms(=5초) 이후에 console 문을 실행한다는 의미이다.

setTimeout(() => {console.log("첫 번째 메시지")}, 5000);

따라서 나는 컴포넌트에서 새로운 빈 데이터를 하나 만들고, 그것을 보여주는 조건 변수(예를 들어, "show") 하나를 false로 초기 설정했다.

그리고 나서 created 시점에서 axios로 가져온 결과 데이터를 새로운 빈 데이터에 넣은 다음 setTimeout을 활용해서 1초 후에 show=true로 바꿔줬다.

이렇게 하면 데이터를 가져올 충분한 시간이 주어지고, 그 다음에 화면에 띄워지게 된다. 일종의 로딩을 걸어준다고 이해하기 쉽다.

문제는, 우리가 딜레이 시간을 정하는 것이기 때문에 데이터 요청이 얼마나 걸릴지를 어림짐작해야 한다.

따라서 만약 우리 예상보다 너무 빨리, 혹은 너무 천천히 데이터 요청이 들어온다면 또 문제가 생길 것이기 때문에 결국은 편법이라고 볼 수 있다.

- 하지만 당장 프로젝트 개발이 바쁘다면 일단 이렇게 하고 나중에 해결방법을 더 찾아봐도 된다.-

 

 

2. 정석대로 해결: v-if

이렇게 급한 불은 껐는데, 생각을 해보니까 setTimeout 없이 해결할 수 있었다.

위의 방법과 마찬가지로 컴포넌트 단위에서 null 값을 가진 새 데이터를 만들어주고, created에서 필요한 action을 호출해서 axios 요청 결과값을 해당 데이터에 넣어준다.

그리고 새 데이터가 있을 때 하위 컴포넌트를 연다는 v-if 문을 쓰면 updated 시점에서 한 번 더 함수를 호출하거나 할 필요없이 간단하게 해결된다.

 

 

느낀점

개발하다 보면 유난히 막힐 때가 있는데, 그게 오늘이었던 것 같다.

계속 함수나 데이터 처리과정이 머리에서 그려지지 않고 계속 뒤섞여서 이번 에러도 해결하는 데 4시간이 넘게 들었다.

이렇게 정리하고 나면 다음에는 훨씬 빨리 해결할 수 있지 않을까 생각한다.

Comments