여섯째주 #26 NextJs - layout패턴, api 숨기기 등

김선은·2023년 6월 21일

layout 패턴

_app.js 에서 공통 컴포넌트 사용할 때

📂 _app.js

export default function MyApp ({ Component, pageProps }) {
	return (
    <>
    	<NavBar />
        <Component {...pageProps} />
    </>
    );
}
  • 전체 화면의 청사진 같은 파일.
  • NavBar를 먼저 그려지고, <Component {...pageProps} />에 각 컴포넌트들이 불러와진다.

coutom app component를 사용할 때 쓰는 layout 패턴을 알아보자

📂 Layout.js

export default function Layout({children}) {
	return (
    <>
      <NavBar />
      <div>{children}</div>
    </>
  );
}
  • children: 하나의 component를 또 다른 component안에 넣을 때 씀
  • _app.js 에서 NavBar를 지우고 Layout 으로 감싸준다.
  • _app.js 파일이 커지는 것을 방지해줌
📂 _app.js

export default function MyApp ({ Component, pageProps }) {
	return (
      <Layout>
        <Component {...pageProps} />
  		// Component에 about.js에 있는 about 함수가 불러와져서
  		// 보여짐. <About /> 이런 식으로 렌더링 하지 않고
  		// 프레임워크가 알아서 일하는 중
  	  </Layout>
    );
}
  • next.js가 Home(index.js)를 받아서 pageProps 자리에 넣고 render를 하면서 getServerSideProps(index.js)를 호출함
  • getServerSideProps는 API을 fetch해서 results를 뽑아서 props:{results}를 return함
  • next.js가 그 props를 pageProps 자리에 넣을 것임

head component - 탭의 title 변경

next 패키지 사용

import Head from "next/head";
react helmet처럼 다운로드 받지 않아도 된다

<<Head>
  <title>Home | Next Movies</title>
</Head>

Head 컴포넌트안에 title 컴포넌트에 작성해 주면 간단하게 사용 가능
여러군데 편하게 사용하기 위해 함수로 만들자

<export default function HeadTitle({title}) {
	return (
      <Head>
      	<title>{title}</title>
      </Head>
    );
}

사용할 때

<HeadTitle title="Home" />

next.js의 public

next.js를 이용하면 public 파일들을 쉽게 다룰 수 있음

📂 public 폴더 안에 vercel.svg가 있는 상황.
<img src="/vercel.svg" /> 으로 사용 가능.

API key 숨기기

next configuration file

redirect

  • user가 URL이 바뀌는 것을 볼 수 있음

📂 next.config.js

module.exports = {
  reactStrictMode: true,
  async redirects(){
  	return [
      {
        source: "/contact", // user가 contact로 가면
        destination: "/form", // form으로
        permanent: false // redirection이 영구적인지 아닌지.
        // 브라우저가 정보를 기억하는지 여부를 결정함
      }
    ]
  }
}

참고: /blog/:path* 주소 뒤에 별표를 붙여주면 모든 것을 catch

rewrites

  • rewrites는 유저를 redirect 시키지만 URL은 변하지 않음
  • 아래처럼 API KEY를 감출 수 있다.
    📂 next.config.js
<const API_KEY = "asd123~~~";

module.exports = {
  reactStrictMode: true,
  async rewrites(){
  	return [
      {
        source: "/api/movies", // fetch의 주소를 얘로 바꿔야함
        destination: `https://api~~~?api_key=${API_KEY}`,
        permanent: false
        
      }
    ]
  }
}

📂 index.js
...
const {results} = await (await fetch(`/api/movies`)),json()
...

env. 파일 이용하기

.env 형식의 environment 파일을 만든다

📂 .env
API_KEY = asd123~~~
//API_KEY를 .env에 저장

📂 next.config.js

const API_KEY = process.env.API_KEY;
//.env에서 값을 받아옴.

📂 .gitignore
.vercel
.env // 여기서 추가해줘야 github로 push가 안된다!!

Server Side Rendering

화면을 먼저 render 하고 데이터 받아오기?
server side를 통해 props를 page로 보낼 수 있다.

getServerSideProps 함수 사용하기!

함수 이름이 중요함! 무조건 저 이름이어야 한다.
이 코드는 server에서 돌아갈 것임!
rewriets를 쓰는 대신 이곳에 API Key를 써도 된다!

📂 index.js
export default function Home({results}) {
  return (
  <div className="container">
    {results?.map((movie) => (
    <h4> {movie.original_title} </h4>
  ))}
  </div>
  )
}


export async function getServerSideProps() {
  const { results } = await (await fetch(`http://localhost:3000/api/movies`)).json();
  // 절대 경로를 써줘야 한다. server가 알려면..
  return {
    props: {
      results // 이 results는 Home에서 프롭스로 줘야함
    },
  };
}
  • 이 함수는 props라는 키를 가진 객체를 리턴한다. props에는 원하는 데이터를 아무거나 넣을 수 있음

  • getServerSideProps는 server에서 실행된다.

  • 무엇을 return 하던지 이걸 props로써 page에 준다.
    nextJs가 백엔드에서 받아온 props를 return해서 Home에 가져다 주면 reactJs가 prop를 가져와서 result array를 뽑아준다.

  • loading이 없어지지만 API가 돌아오기 전까지 화면에 아무것도 안보임

선택해야 함!

  • 항상 server side rendering을 하고 싶은지?
    즉 데이터가 유효할 때 화면이 보여지게 할 것인지
  • 또는 loading 화면을 보여 준 다음에 데이터를 받게 할 것인지?

getServerSideProps 레거시 됨

next.js 13 버전에서는 다른 방식으로 적용된다고 함.

next.js 13버전 부터는 App router를 이용하며 getServerSideProps 등의 방식은 적용되지 않는다고 합니다(https://nextjs.org/docs/app/building-your-application/data-fetching#old-methods). 대신 새로운 방식을 도입했는데 이게 더 쉽고 간편하고 깔끔한 것 같습니다.
App router에서 작업하시는 분들이 계신다면 공식 문서 예시 코드 보시면 도움 되실 것 같아요(https://nextjs.org/docs/app/building-your-application/data-fetching/fetching).

next 13.4 버전 기준으로 getServerSideProps 대신에 fetch에 옵션 ('no-store')을 주어 SSR을 구현할 수 있습니다. (기존 getServerSideProps는 레거시가 되었다고 합니다.)

https://ahnanne.tistory.com/92
참고하여 작성하였습니다!

async function fetchData() {
const res = await fetch('http://localhost:3000/api/movies', {
cache: 'no-store',
})
const { results } = await res.json()
return results
}

export default async function Home() {
const results = await fetchData()
return (
*div*
{results?.map((movie: any) => (
... (코드 동일)
))}
*/div*
)
}

추가로 읽어보기

next.config.js

Next.js에서 커스텀 설정을 하기 위해서는 프로젝트 디렉터리의 루트(package.json 옆)에 next.config.js 또는 next.config.mjs 파일을 만들 수 있습니다. next.config.js는 JSON 파일이 아닌 일반 Node.js 모듈입니다.
Next.js 서버 및 빌드 단계에서 사용되며 브라우저 빌드에는 포함되지 않습니다.
https://nextjs.org/docs/api-reference/next.config.js/introduction

Redirects (URL변경됨)

Redirect을 사용하면 들어오는 request 경로를 다른 destination 경로로 Redirect할 수 있습니다. Redirect을 사용하려면 next.config.js에서 redirects 키를 사용할 수 있습니다.

redirects은 source, destination 및 permanent 속성이 있는 객체를 포함하는 배열을 반환하는 비동기 함수입니다.
source: 들어오는 request 경로 패턴 (request 경로)
destination: 라우팅하려는 경로 (redirect할 경로)
permanent: true인 경우 클라이언트와 search 엔진에 redirect를 영구적으로 cache하도록 지시하는 308 status code를 사용하고, false인 경우 일시적이고 cache되지 않은 307 status code를 사용합니다.
https://nextjs.org/docs/api-reference/next.config.js/redirects

Rewrites (URL변경되지 않음)

Rewrites를 사용하면 들어오는 request 경로를 다른 destination 경로에 매핑할 수 있습니다.
Rewrites은 URL 프록시 역할을 하고 destination 경로를 mask하여 사용자가 사이트에서 위치를 변경하지 않은 것처럼 보이게 합니다. 반대로 redirects은 새 페이지로 reroute되고 URL 변경 사항을 표시합니다.
https://nextjs.org/docs/api-reference/next.config.js/rewrites

Movie Poster Path
https://image.tmdb.org/t/p/w500/${movie.poster_path}

주의! fetch할 때 /api/movies 또는 http://localhost:3000/api/movies 둘 다 가능하지만 http가 아닌 https로 fetch하게 되면 오류가 발생합니다.


getServerSideProps

page에서 서버 측 랜더링 함수인 getServerSideProps함수를 export하는 경우 Next.js는 getServerSideProps에서 반환된 데이터를 사용하여 각 request에서 이 페이지를 pre-render합니다. getServerSideProps는 서버 측에서만 실행되며 브라우저에서는 실행되지 않습니다.
https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props

getServerSideProps를 사용하여 request시 데이터 fetch하기
다음 예는 request 시 데이터를 fetch하고 결과를 pre-render하는 방법을 보여줍니다.
(fetch할 때 오류 뜨시는 분들은 https를 http로 바꿔주시면 됩니다.)

<export default function Home({ data }) {
// 데이터 랜더링
}

// 매 request마다 실행됩니다.
export async function getServerSideProps() {
const res = await fetch(`https://.../data`);
const data = await res.json();

// props를 통해 page에 data전달
return { props: { data } }
}

https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props#using-getserversideprops-to-fetch-data-at-request-time

getServerSideProps (타입스크립트와 함께 사용하기)
https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#getserversideprops-with-typescript

profile
기록은 기억이 된다

0개의 댓글