kok202
Next.js

2020. 2. 16. 07:27[정리] 직무별 개념 정리/프론트엔드

강의 링크

강의 문서

 

장점

- 서버 사이드 렌더링

- 검색 최적화

서버 사이드 렌더링 : 리액트로 만들어진 앱들은 자바스크립트가 동작하지 않는 환경에서 소스보기를 했을 때, 실제 보이는 값과 다르게 안 보이는 컨텐츠들이 있을 수 있다. 

 

설치

npm add next
npm add react
npm add react-dom

 

package.json 스크립트

...
"scripts": {
  "start": "next",
  "build": "next build", // .next/server/static/{cache}/ 아래 빌드된 파일이 만들어진다.
  "export": "next export", // 빌드한 파일이 out 이라는 디렉토리에 SPA 파일이 만들어진다.
  ...
}
...

 

pages 폴더

Web 사이트를 만들기 위한 프레임워크. 리액트 돔이 아닌 pages 폴더로 라우팅 관리한다.

 

Link 태그

앵커 태그가 아닌 next/link 컴포넌트를 사용한다. SPA 상에서의 이동이 된다.

Next 에서 앵커 태그로 이동하면 페이지 전체가 리로딩 되는 방식이 된다.

 

Head 태그

해당 페이지에서만 적용할 헤더 파일을 지정할 수 있다.

페이지별로 Head 태그와 title 을 같이 적어주는 것을 권장하고 있다.

 

라이프사이클

Next.js 서버 (웹 서버)
1. Next 의 getInitialProps
서버에서 미리 읽어야하는 작업을 넣는다.
해당 컴포넌트를 생성하기 전 단계에 읽어야하는 자료를 읽는 동작을 여기에 넣는다.
서버 사이드 렌덩이 필요한 작업을 넣는다.
2. constrcutor 도 서버 렌더링 과정에 포함된다.

 

Next.js 클라이언트 (사용자)
3. react 의 useEffect
서버 사이드 렌더링을 안해도 되는 작업을 넣는다.

 

pages/_document

예약된 페이지 이름.

html 기본 헤더, 메타 선언(부트스트랩)과 같은 모든 페이지에서 넣어줘야할 때 내용이 있을 때, 해당 문서를 사용한다.

- 리액트 컴포넌트와 비슷하게 생겼지만 리액트 컴포넌트는 아니다.

- 서버에서 실제로 단 한번만 실행된다.

- SPA 에서 변경할 수 없다.

- 동적으로 돌아가는 스크립트 파일이 아니다.

- 헤더안에 title을 쓰는 것은 권장하지 않는다.

Main : Next 에서 실제로 Next 클라이언트가 동작하는 파일을 어디에 넣을지 위치 지정한다.

NextScript : Next 에서 번들링된 파일을 어디에 넣을지 위치 지정한다.

 

pages/_app

예약된 페이지 이름.

공통되는 부분, 기본 레이아웃을 설정할 때 사용한다.

- Navigation

- Footer

- componentDidCatch 에서 에러 캐치

- 그외 공통 컴포넌트 (modal, load block)

 

Styled-component

next 를 styled-component 와 같이 사용할 경우 약간의 튜닝이 필요하다.

서버사이드 렌더링할 때 style 이 렌더링되고

클라이언트 렌더링할 때 style 이 한번더 렌더링 되기 때문이다.

프로젝트 최상위 경로에 .babelrc 파일을 만들고 아래 내용을 넣는다.

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "styled-components",
      {
        "ssr": true,
        "displayName": true,
        "preprocess": false
      }
    ]
  ]
}

ssr : 서버사이드 렌더링에서 스타일드 컴포넌트를 만들 때 서버사이드에서 만든것과 프론트에서 최초 만든 것을 비교하여 클래스 불일치로 인한 오류를 방지하는 옵션

displayName : 스타일드 컴포넌트로 생성된 클래스 이름이 조금이라도 구분할 수 있는 수준으로 만들어지도록 하는 옵션

 

컴포넌트에 key 를 유니크하게 만드는 방식

1. new Date().getTime().toString()

2. Math.random()

3. uuid

 

getInitialProps

function Page({ stars }) {
  return <div>Next stars: {stars}</div>
}

Page.getInitialProps = async ({ req }) => {
  const res = await fetch('https://api.github.com/repos/zeit/next.js')
  const json = await res.json()
  return { stars: json.stargazers_count }
}

export default Page

코드 출처 링크

getInitialProps 가 return 한 값이 MyFunction 의 props 로 전달해준다.

 

 

 

* Server 쪽에서는 브라우저에서 제공하는 localStorage 와 같은 기능이 없다. 그래서 리액트 컴포넌트 코드에 localStorage 와 같은 것을 사용하면 SSR 할 때 서버쪽에서 코드가 돌아갈 때 에러가 날 수 있다. (같은 컴포넌트를 공유해서 사용하므로) 따라서 localStorage 와 같은 동작은 useEffect 영역에 넣어줘야한다.