기능 공유 및 에러핸들링

Next.js에서 react-query 활용한 무한스크롤 완전정복(useInfiniteQuery, useLocalStorage)

Fo_rdang 2024. 3. 24. 21:42
반응형

눈물이 좀 날 뻔 했다. 

다른 FE 개발자 분들은 헤매지 마시라고 기록을 남긴다. (...빠이팅! )

 

거두절미하고 바로 시작 

 

00. 백엔드에서 가져와야할 데이터 형식

내가 백엔드에서 받아온 데이터 형식은 이렇다. 

만약 백엔드에서 가져온 데이터가 pageNo(이 데이터가 몇번째 페이지인지 나타냄)나 totalPages(총 전체 페이지가 몇개인지 나타냄)를 포함하고 있지 않다면 곤란하다. 

없다면 공손하게 백엔드 분께 부탁드리자. !

 

1) swagger에서 볼 수 있는 response

 

2) front에서 보는 데이터. 

(나는 data로 된 이름이 2개여서

이해를 쉽게 돕고자 더 큰 data를 data1, 그 아래 실제 데이터 갖고 있는 data를 data2 로 이야기를 할 예정이다. )

 

내 백엔드 분은 다양한걸 넣어주셨는데 난 잘 활용을 못한 것 같다. 

그래도 설명해보자면 

- hasNext : 다음 페이지가 있으면 true

- pageNo: 현재 가져온 데이터가 몇번째 페이지인지 나타냄 

- pageSize: 현재 페이지의 데이터 개수 

- totalElements: 총 데이터 개수 

- totalPages: 전체 페이지 수 

이 중 나는 pageNo와 totalPages만 활용했다. ! 

01. 설치

axios랑 react-query를 설치하자 

 npm i axios react-query

 

02. _app.tsx 파일 작성

나는 Next.js의 pages router를 쓴다. 

그래서 _app.tsx 파일에서 react-query를 쓰기 위해 코드를 작성해준다. 

 

03. 무한스크롤을 위한 코드 작성

01) 백엔드에서 데이터 가져오기 

 

- axios를 활용해서 비동기적으로 데이터를 가져온다. 

- pageParam은 1로, 첫번째로 가져오는 페이지가 1이 된다는 뜻이다. 

- ${백엔드 주소} 라고 적힌 곳에 실제 백엔드 주소를 넣으면 된다. 

- 나는 size를 12로 설정해서 1페이지에 데이터를 12개씩 가져온다. 

 

02) useInfiniteQuery 활용하기 

 

- ["allPerformances"] 이 부분은 자유롭게 데이터 이름을 설정해주면 된다. 

- 위에 우리가 작성한 함수(getPerformanceWithPageInfo)를 호출한다. 

- getNextPageParam 함수는 1페이지부터 시작해서 +1 을 더하면서 끝 페이지에서 함수 호출(getPerformanceWithPageInfo)을 멈추게 하는 함수다. 

- lastPage.data.pageNo 에서 data는 data1을 의미한다.(쓰는 data가 두개라서 설명하기 쉽게 data1, data2로 부르기로 위에서 말함) 

 

04. 알고가기 

npm run dev를 할 때 

자신이 개발하고 있는 화면을 볼 수 있다. 

그 왼쪽 밑에 이걸 눌러보자. 

그리고 우리가 아까 작성해준 데이터의 이름을 클릭한다. 

그러면, 오른쪽 부분에 데이터가 들어온걸 확인할 수 있다. 

- pages는 fetch callback을 통해 return 된 page 객체의 배열을 가지고 있다. 

- pageParams는 useInfiniteQuery가 현재 어떤 페이지에 있는지를 확인 할 수 있는 파라미터 값이다. 

05. return 부분

 

왜 04번에 알고가기를 넣었는지 이제 알 수 있다. 

데이터를 map으로 뿌릴 때 ,

data.pages로 한번 접근한 후에야 백엔드에서 가져온 데이터로 접근 할 수 있다. 

즉, map을 두번 써야 한다는 뜻 ! 

 

06. 전체 코드 

전체 코드를 첨부하자면 이렇다. 

근데 여기서 배신감을 느끼시는 분들이 있을 것. 

주석 처리 된 부분을 설명을 안하지 않았는가? 

이 부분은 사용자가 화면을 바닥까지 내렸을 때를 감지하게 하는 코드다. 

이제 이 부분은 다른 분의 블로그를 사뿐히 첨부하고 갈 예정이다. 

왜냐하면, 이 부분은 헤맨 곳이 없다. 그대로 따라하면 될 것이다. 

 

07. 블로그 첨부 

https://mingmeng030.tistory.com/277

 

[NextJs] React-Query의 useInfiniteQuery로 무한스크롤 구현하기

nextjs+typescript+tailwindcss 환경에서 영화 api를 사용한 토이 프로젝트를 진행중이다. (영화 api https://developer.themoviedb.org/reference/intro/getting-started) https://mingmeng030.tistory.com/270 axios .get(`${config.api}/api/searc

mingmeng030.tistory.com

 

08. useLocalStorage 

무한 스크롤의 위치를 저장하기 위한 라이브러리다.  브라우저의 localStorage에 저장하는 것인데 

왜 위치를 저장해야 할까? 

사용자가 실컷 무한 스크롤을 통해서 페이지를 내린 후, 하나 정보가 마음에 들어서 클릭해서 상세 페이지를 봤다가 

다시 이전으로 돌아갔을 때, 

위치가 저장이 안되면 

사용자는 다시 처음부터 스크롤을 열심히 내려야 하는 화나는 상황이 생긴다. (나도 이런 적이 있다...)  

 

1) 설치 

npm i use-local-storage

 

2) 사용법 (간단하다!)

	const [value, setValue] = useLocalStorage("name", initialValue)

 

useState 방식과 같다. 다만, 두개의 인자를 받는다. 

첫번째 인자는 데이터의 key 이름을 설정하는 것.

두번째 인자는 처음 값을 설정한다. 

 

3) 특징 

useLocalStorage는 로컬 스토리지의 값을 React 컴포넌트의 상태로 가져와서 변경될 때마다 자동으로 화면을 다시 렌더링한다. 

 

설명: 원래는 react에서 localStorage에 접근해서 값을 쓰고 가져온다 해도 state가 아니기 때문에 화면을 다시 렌더링 하지 않는 것이 일반적인데, useLocalStorage는 localStorage에 값을 저장하면서도 값이 변경될 때마다 화면을 업데이트한다. 따라서 코드를 더 간결하고 유지보수하기 쉽게 만든다. 

 

4) 코드 작성

 

useLocalStorage를 import 를 해준다.
함수 안에 useLocalStorage 코드를 작성해준다

 

나는  "performance_scroll"로 설정했고, 처음값은 0이다. 

해당 공연을 클릭했을 때 set 함수 실행되는 코드

 

해당 공연의 세부 페이지로 들어가는 Link 태그다. 

이걸 사용자가 눌렀을 때 그때의 위치(window.scrollY)를 localStorage에 저장하는 것이다. 

 

 

스크롤 위치가 0 이 아닐 경우, 해당 스크롤 위치를 저장한다. 

 

5) 결과 

사용자의 scrollY가 저장된 모습

애플리케이션 탭에서  로컬 스토리지를 클릭하면 

내가 설장한 performance_scroll 이라는 이름을 값이 설정된 것을 볼 수 있다. 

반응형