NextJs[2] data fetching

jinjoo-jung·2024년 8월 18일

data fetching

기존 방식

react app = > api 통신 => api로 데이터베이스와 통신 => 완료 => 데이터베이스에서 다시 api를 통해 응답전달

  • client에서 fetch하면 좋지 않다 왜?
    => 보안을 위해 항상 api를 중간에 만들어야 하고, 데이터베이스에 직접 통신할 수 없기 때문 . 먼저 api에 요청을 보내고 api가 안전한 환경에 있다면 그 뒤에 데이터베이스에 요청을 보낸다.
    => 이 방식은 나아질 수 있다 . 우리의 nextjs 백엔드가 api없이 직접 데이터베이스와 통신할 수 있다면.

로딩 상태 구현도 직접 확인해야함 SWR이나 리액트 쿼리를 통해서. isLoading이 뭐면~ 보여주고 등등
nextjs나 다른 프레임워크를 사용하지않을 때 리액트 앱에서 이렇게 구현된다. 항상 useState를 써야하며(처음엔 컴포넌트가 비워져있기때문), 수동으로 setState를 해주고, 이건 render를 발생시킨다. 즉 스스로 모든걸 관리가 필요하다.

  • 이게 serverccomponent에서 fetch를 사용하기 이전의 상황이다
  • serverccomponent에서 fetch를 한다는 것은 useEffect를 쓰지 않아도 된다는 것이다. useState도 사용하지 않고, 로딩상태도 구현하지 않는다. 프레임워크가 대신 해줄것이기 때문. 신경써야할것은 serverccomponent에서 비롯되어야한다는 것이다.
  • useState를 썼기 때문에 metadata를 쓸 수 없다. client component에서 사용할 수 없기 때문.

** 정리
useEffect, useState와 같은 도구들로 fetch 하고 response를 await하고 state를 다시 set, 로딩도 직접 구현. => 이렇게 client에서 react가 작동하기 때문에 리액트 앱이 항상 api를 신경써야 하고, 데이터베이스와 통신을 했어야했다. 백엔드 개발자는 항상 api와 통신해야만 했고, api를 만들어야했다. 그래야 프론트엔드 즉 리액트 앱이 api와 통신할 수 있기 때문.

- 최신 버전의 nextj serverccomponent가 있다면 api는 더이상 필요 없다.

전에는, 모든 fetch가 client에서 이루어졌다. 그래서 사용자가 도착하는 순간 Home이나 About Us를 볼 수 있었지만 , 아래에서 로딩중 상태를 봐야했고 그리고 fetch를 위한 코드도.. 재밌지 않았다.

  • 지금은 Home이나 AboutUs를 보지도 못 하고 있으며 (데이터가 도착할 때까지) 우리가 Layout, not found 같은 기본 컴포넌트가 있는 것처럼 로딩도 있다.

NextJs data fetching

serverccomponent에서 fetch는 , 데이터를 fetch하는 코드를 작성하고 그걸 우리의 컴포넌트에 넣으면 됐다. 그러면 백엔드에서 fetch가 되고 결과를 사용자에게 보여주었다. 그러나 이렇게 작성한 코드는 사용자에게 전달되지 않는다. (=완벽히 안전) 원하는 어떤 데이터는 fetch 할 수 있다. 원하는 모든 API key를 쓰거나 여기서 데이터베이스와 통신도 할 수 있다.
여기서 문제는? 데이터를 불러오는데 긴 시간이 걸리고, 사용자를 위한 UI가 없을 것이다. 왜냐하면 이 fetch 코드는 백엔드에서 fetch가 되기 때문.

  • fetch함수가 완료되기 전까지는 백엔드에서 렌더링 작업이 이루어지지 않을 것이다. 그러면 사용자는 아무것도 볼 수 없다. 위에 뜨는 로딩만 볼 수 있음

해결방법

loading.tsx파일을 만든다


. 여기서 로딩중이 뜬다는 것은 백엔드에서 무언가가 일어나고 있는 것이다.


자동으로 loading.tsx에 작성한 코드만으로 아래 로딩 ui를 보여줄 수 있다.
프레임워크는 이 모든 걸 해준다. serverccomponent에서 fetch 하는 중에 로딩 파일을 제공해주면 그 파일이 페이지에 나타난다. 그리고 serverccomponent가 fetch를 끝내면 nextJS는 로딩 컴포넌트를 바꿔줄 것이. 페이지의 컴포넌트로.

= 페이지가 content를 streaming하기 때문. 백엔드가 content를 streaming하고 있다.

NextJS는 사용자가 페이지에 도착하는 순간 loading component를 볼 수 있게 하고 그 다음 백엔드가 이 함수에서 fetch가 완료되면 백엔드가 브라우저에 완료된 결과값을 보내는 것이다.

위 코드가 결과값이다.

  • NextJs는 브라우저에 웹사이트의 일부분을 천천히 주면서 아직 작업이 끝나지 않았다고 계속 말하고 있다. 첫번째로 브라우저에 layout과 loading component를 주면서 계속 기다려달라고 한다. 그리고 다 끝나고 나면 결과값이 있는 컴포넌트가 브라우저에게 전달되고 그 다음 로딩 컴포넌트가 교체된다.

이때 HomePage 컴포넌트가 async여야하는 이유는 nextjs가 이 컴포넌트에서 await 해야하기 때문.
사용자가 우리 웹사이트에 도착하는 순간 nextjs는 즉시 사용자에게 로딩 상태를 줄것이. => 하지만 streaming을 사용하면서 nextjs는 기본적으로 우리의 페이지를 작은 HTML 부분으로 나누어서 준비된 HTML 부분을 브라우저에 줄 수 있다. navigation bar나 로딩 컴포넌트 같은 부분들. (사용자에게 보일 준비가 될). 이 HTML부분들은 브라우저에 즉시 전달 되고 브라우저에게 백엔드에서 통신이 아직 마무리 되지 않았다고 기다려야한다고 우리는 컴포넌트를 awati하고 있으며 await가 끝나면 브라우저에게 마지막 HTML부분을 전달해주는 것이다. 그러면 프레임워크가 로딩컴포넌트를 await된 컴포넌트로 바꿔주는 것이다.

-**순서 정리
1. 사용자가 페이지에 도착해 우리가 만든 로딩 컴포넌트를 본다
2. 그동안 넥스트는 HomePage component를 await한다.
3. nextjs가 이 컴포넌트를 await하고 HTML결과를 기다린다.
4. 이 때 우리가 하는 건 로딩중이면 사용자에게 이 로딩컴포넌트를 보요주고 아니라면 HTML(원래 리액트에서 작성한 부분들을 백엔드에서 한다고 생각하면 됨)


로딩 페이지는 page파일 옆에 있어야 한다.

profile
개인 개발 공부, 정리용 🔗

0개의 댓글