4.3 Next.js 톺아보기
4.3.1 Next.js란?
- 리액트의 SSR 기반으로 작성된 프레임워크 Next.js
4.3.2 Next.js 시작하기
✅ package.json
- 명령어 및 의존성
- next 버전 및 타입스크립트에 필요한 @types
- ESLint 설정
✅ next.config.js
- next 의 환경 설정 파일
- reactStrictMode : 리액트의 엄격 모드 옵션
- swcMinify : 보다 번들링, 컴파일 빠르게 수행하는 Rust 기반 번들러를 사용할 것인지에 대한 옵션
Page Router 기반
✅ pages/_app.tsx
- next 애플리케이션의 페이지 시작점
- 전역 CSS, 전역에서 사용하는 데이터 등 전역에서 공통으로 필요한 옵션 설정하는 파일
- 렌더링이나 라우팅에 따라 서버,클라이언트에서 실행
- 애플리케이션 페이지 전체 초기화
✅ pages/_document.tsx
- 애플리케이션의 HTML 서식을 설정
- 서버 사이드에서 실행
- next가 제공하는 2개의<head/>
- next/head : 실제 head 태그와 동일한 작업
- next/document <Head />
- 실제 head 태그를 감싸는 역할
- _document.tsx에서만 사용
- <title/> 사용 X
✅ pages/_error.tsx
- 클라이언트,서버에서 발생하는 500에러 처리
- 전역에서 발생하는 에러 처리
✅ pages/404.tsx, pages/500.tsx
- 404, 500 에러 시 보여지는 페이지
✅ pages/index.tsx
- Next에서 제공하는 페이지가 아닌 개발자가 자유롭게 사용하는 페이지
- /pages의 디렉토리를 따름
- 전개 연산자 활용
pages
├── index.tsx
├── hello
├── [...params]
localhost:3000/hello/seoyoung 를 입력하면
params에 hello와 seoyoung이 각각 들어가고 해당 페이지 렌더링
pages
├── index.tsx 웹 사이트의 루트 localhost:3000
├── hello
├── index.tsx localhost:3000/hello
├── seoyoung.tsx localhost:3000/hello/seoyoung
├── [age].tsx 변수 localhost:3000/hello/25
├── world
├── index.tsx localhost:3000/hello/world
📍서버 라우팅과 클라이언트 라우팅의 차이
- next에서 제공하는 <Link> ,<a> 처럼 페이지 이동하는 라우팅 컴포넌트
- <a>
- 이동하는 페이지의 HTML과 필요한 리소스를 모두 다운
- 화면 깜빡임
- <Link>
- 클라이언트에서 필요한 JS 파일만 다운
✨prefetch
- “미리 받아온다”
- 이동할 페이지의 리소스를 미리 받아오는 것
- 좀 더 빠른 페이지 전환
- 페이지의 모든 Link가 아닌 뷰포트(사용자에게 현재 보이는 화면) 내 Link한정
내부 페이지 이동 시
- <a> 대신 <Link> 사용
- window.location.push 대신 router.push 사용
📍 getServerSideProps 유무
- Next가 SSR이지만 모든 작업이 서버에서 일어나지 않음
- getServerSideProps는 서버로부터 데이터를 받는 작업
- getServerSideProps을 사용하지 않으면 SSR이 필요하지 않은 정적 페이지로 분류됨
✅ pages/api/hello.ts
pages
├── api
├── hello.ts
- 서버의 API를 정의하는 폴더
- HTML 이 아닌 서버 요청 (fetch)
- export default로 보낸 함수 실행
- 서버에서 실행되기 때문에 window, document 등 브라우저에서 접근할 수 있는 코드 X
4.3.3 Data Fetching
- next에서 SSR 지원을 위한 데이터 패칭 함수
- pages 폴더 내에서 사용해야 하며 export 필수
✅ getStaticPaths와 getStaticProps
- 정적된 페이지에 사용
- 두 개 함수는 반드시 함께 사용
getStaticPaths
- 접근 가능한 주소 정의하는 함수
- fallback 옵션
- paths에 지정해둔, 즉 미리 빌드 타임에 생성해두지 않은 path로 요청이 들어온 경우 결정하는 옵션
- false
- 404 페이지 라우팅
- 적은 수의 path만 프리렌더링하는 경우
- true
- 빌드 되기 전까지 fallback 컴포넌트를 보여주고, 빌드가 완료되면 해당 페이지 보여줌
- 새롭게 생성된 페이지를 기존 빌드 시 프리렌더링된 페이지 리스트에 추가 (이후 요청 들어오면 fallback 컴포넌트가 아닌 페이지 반환)
- 미리 빌드할 페이지가 너무 많은 경우, 빌드 시간 단축 위함
- “blocking”
- true일 경우와 비슷하게 동작하지만 fallback을 보여주지 않고 동작
getStaticProps
- getStaticPaths로 정의한 페이지 기준으로, 해당 페이지 요청이 들어오면 제공한 props를 리턴하는 함수
- 빌드 시점에 미리 데이터를 불러와 페이지를 정적 빌드
- 빌드해 두기 때문에 추후 요청 시 빠르게 사용자에게 제공됨
- 정적인 데이터를 제공하는 경우 사용
✅ getServerSideProps
- 페이지 진입 전 함수 실행
- 함수 응답 값에 따라 루트 컴포넌트에 props 반환 혹은 리다이렉트 처리
- 렌더링에 필요한 데이터는 __NEXT_DATA__ id가 지정된 script에 저장
- 서버에서 가져온 데이터를 클라이언트에 전달하는 역할
- Data Fetch, HTML 생성, 클라이언트 전송, Hydration 순으로 진행하는데 각 작업 별로 fetch 시점에 따라 결과물이 불일치 → ??
- getServerSideProps의 props로 내려준 값은 JSON 형식으로 반환되기 때문에 반드시 JSON.stringify로 직렬화할 수 있는 값이어야 함 !
- ✨ 서버는 자신의 호스트를 유추할 수 없기 때문에 API 호출 시 프로토콜과 도메인을 사용해야 함 (완전한 주소!!!!)
- 페이지를 호출할 때마다 실행되고, 실행이 끝나기 전 다른 HTML 보여줄 수 없기 때문에 꼭 필요한 데이터만 가져올 것
응답에 따른 redirect
- 데이터 패칭 중 오류날 경우 리다이렉트
- 클라이언트에서 리다이렉트보다 자연스러움
✅ getInitialProps
- getServerSideProps, getStaticProps 이전 유일한 SSR 데이터 패칭 함수
- 현재는 _app.tsx 등에서만 사용됨
- 페에지의 루트 함수에 정적 메서드
- props 객체가 아닌 바로 객체 반환
function Page({ stars }) {
return <div>Next stars: {stars}</div>
}
Page.getInitialProps = async (ctx) => {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const json = await res.json()
return { stars: json.stargazers_count }
}
export default Page
- 페이지가 처음 로드되는 경우 기본적으로 서버 사이드에서 실행
- Link 혹은 router를 통해 라우팅될 경우 클라이언트 사이드에서 실행
- 서버와 클라이언트 모두에서 실행함
💡context 객체
- params : 동적 경로를 사용하는 경우 , 경로 변수가 포함
- req : HTTP request 객체 (IncomingMessage ) , 쿠키 값인 문자열 키가 있는 cookies 속성도 있음
- res : HTTP response 객체 (ServerResponse)
- query : URL에 존재하는 쿼리, [id]와 같은 변수 포함
- asPath : 사용자가 보는, 브라우저에 표시되는 실제 경로 “/todo/1”
- pathname : 현재 경로명, 페이지 상의 경로 “/todo/[id]”
4.3.4 스타일 적용하기
- Next.js 다양한 스타일 지원
✅ 전역 스타일
- reset,global CSS 등 어플리케이션 전체에 공통으로 적용하고 싶은 경우 _app.tsx 활용
✅ 컴포넌트 레벨 CSS
- [name].module.css처럼 명명 규칙 준수
- CSS 클래스가 중첩되는 것 방지하는 역할
✅ SCSS와 SASS
- 모듈 css랑 같이 사용하면 편함 .. !
- 중첩, mixin, 변수 등
✅ CSS-in-JS
- 자바스크립트 내부에 스타일시트를 삽입
- 개발자에게 직관적인 코드, 편리함
- 스타일드 컴포넌트, 이모션 등
- 서버 사이드 렌더링 과정에서 애플리케이션에 쓰이는 스타일을 수집하고 서버 단에서 주입하는 과정을 거침
- CSS - in - JS는 브라우저에서 JS를 실행해서 동적으로 style 태그를 생성하고 이 태그에 스타일을 삽입하기 때문
<style>
.hash136s21 {
background-color: black;
color: white;
}
</style>
<p class="hash136s21">Hello CSS-in-JS</p>
4.3.5 _app.tsx 응용하기
- 페이지 최초 렌더링 시 서버 사이드 렌더링이 전체적으로 작동하기 때문에 _app.tsx에 정의된 getInitialProps 실행
- 이후 Link , router 이용시 클라이언트 렌더링처럼 작동하는데,
- 이때 서버 관련한 로직이 있어도, 전체 페이지가 아닌 해당 페이지의 getServerSideProps 를 실행 (getInitialProps X)
- 이를 활용해 최초에 접근했을 때만 실행할 있는 내용을 _app.tsx 의 getInitialProps 에 정의
4.3.6 next.config.js 살펴보기
- Next.js 실행에 필요한 옵션 설정하는 파일
- basePath: 경로에 대한 접두사
- next/link ,next/router 사용해서 다른 페이지에 연결해도 자동으로 적용
'React > 모던 리액트 Deep Dive' 카테고리의 다른 글
[6장]모던 리액트 Deep Dive 스터디 11회차 (0) | 2024.07.12 |
---|---|
[5장] 모던 리액트 Deep Dive 스터디 10회차 (0) | 2024.07.12 |
[4-1 ~ 4-2] 모던 리액트 Deep Dive 스터디 8회차 (0) | 2024.06.24 |
[3장] 모던 리액트 Deep Dive 스터디 7회차 (0) | 2024.06.17 |
[2-3 ~ 2-5] 모던 리액트 Deep Dive 스터디 6회차 (0) | 2024.06.14 |