노마드코더 Nextjs 강의를 Typescript로

jaehan·2023년 3월 7일
0

next

목록 보기
1/1
post-thumbnail

Nextjs

nextjs 공부를 시작했는데 노마드코더 nextjs 강의가 무료길래 먼저 실습 해보고 도큐먼트를 살펴보려고 한다.

❗️ 강의는 js 강의이지만 나는 ts를 선호하기 때문에 강의 내용을 ts로 정리하려 한다.

내가 이해한 Nextjs

내가 이해한 바로는 Nextjs는 자기 서버가 있어서 서버사이드렌더링을 지원하는 프레임 워크이다.

처음에는 SSR만 지원하는 프레임 워크라 생각했었는데,

개발자가 지정한 부분에 SSR를 적용하고 나머지는 CSR로 React에게 맡기는 형식이라고 이해했다.

따라서 처음에 끊기지 않고 페이지가 들어가 지고(SSR) 페이지 전환시에도 끊기지 않고 이동이 가능했다(CSR).

프로젝트 생성

npx create-next-app@latest --typescript
  • 이걸 입력하면 프로젝트 이름 입력하라고 나오는데 거기에 원하는 이름 입력하면 된다.
    그냥 위 명령어 마지막에 이름을 입력해도 된다.
  • 다음으로 eslint 사용할건지나오는데 이건 YES로 하고 다음부터 나오는건 다 NO설정해 줬다.

폴더 구조

프로젝트를 생성하고 나면 다음과 같이 폴더 구조가 되어있다.

페이지 생성

Nextjs는 React와 다르게 프레임워크 이기 때문에 pages/[이름].tsx 으로 파일을 생성하면 그 파일 자체가 페이지가 되어 localhost:3000/[이름] 이 된다.

index.tsx

우선 처음에 있던 파일을 다 삭제해 주고 index.tsx 파일을 생성해 준다.

안의 내용을 대충 적어주고 npm run dev를 하면 로컬 환경이 켜지는데

localhost:3000에 접속하면 index.tsx 파일이 나온다.

❗️ pages 폴더 아래의 파일은 이름으로 url이 정해지는데 index.tsx는 /로 설정 된다 ex)localhost:3000/

about.tsx

pages/about.tsx로 파일을 만들어서 실행해 보면 localhost:3000/about에 페이지가 나온다

_app.tsx

pages/_app.tsx로 파일을 만들면 이 파일을 항상 먼저 확인하고 다른 파일을 실행 시킨다.

그래서 여기다가 모든페이지의 공통요소(Navbar, Footer, Layout, global.css)를 설정해 주면 중복 요소를 제거해 줄 수 있다.

📌 React 에서의 App.tsx를 생각하면 된다.

import { AppProps } from "next/app";
import "../styles/globals.css";
export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <NavBar />
      <Component {...pageProps} />
    </>
  );
}

404.tsx

Nextjs에서는 404페이지를 편하게 커스텀 할 수 있는데

pages 폴더에서 이름을 404.tsx로 만들면 404 페이지 대신에 우리가 만든 페이지가 나온다.

Folder/...

폴더를 만들고 그 아래에 파일을 만들면
localhost:3000/[folder이름]/[파일이름]
으로 생성된다.

[...params].tsx

위 처럼 파일이름을 설정하면 useRouter를 이용해서 query를 받아올 수 있다.

예를 들어 movies/[...params].tsx를 만들었고

"http://localhost:3000/movies/Knock%20at%20the%20Cabin/631842
로 접속했다고 하자

아래 코드처럼 타입을 지정해서 query를 받아올 수 있다.

type queryType = {
  params: [title: string, id: string];
};
...

  const router = useRouter();
  const query = router.query as queryType;

👇 console.log(router.query)

React router 처럼 Nextjs에도 Link 태그가 있다.

강의에서는 Link안에 className을 지정하지 못하기 때문에 내부에 a태그를 추가해 줬는데 13버전 되면서

a태그를 못넣게 되었고 Link안에 className을 지정할 수 있게 되었다.

<Link href="" className=""></Link>

서버사이드렌더링

fetch data

Nextjs에서는 getServerSideProps를 이용해서 SSR을 지원한다.

강의에서는 아래처럼 타입 지정없이 데이터를 받아와서 페이지로 넘겨줬는데

나는 타입스크립트를 사용하기 때문에 아래처럼 하면 바로 에러가 났다.

export async function getServerSideProps() {
  const { results } = await (
    await fetch(`http://localhost:3000/api/movies`)
  ).json();
  return {
    props: {
      results,
    },
  };
}

그래서 아래처럼 result의 타입을 지정해주고 데이터를 받아와서 페이지로 넘겨줬다.

export const getServerSideProps: GetServerSideProps<{
  results: MovieType[];
}> = async () => {
  const { results } = await (
    await fetch(`http://localhost:3000/api/movies`)
  ).json();
  return {
    props: {
      results,
    },
  };
};

페이지에서 result값을 받는 코드는 아래와 같다

type MovieType = {
  id: string;
  original_title: string;
  poster_path?: string;
};

export default function Side({
  results,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
  ...
}

📌 이 두 코드를 한 파일에서, 페이지 컴포넌트를 위, getServerSideProps를 아래에 작성해야 한다
그래서 코드를 보면 페이지 컴포넌트 위에 타입을 정의해논것이다.

context

getServerSideProps에서 제공하는 context가 있다.

이를 이용해서 서버에서 query string을 받아와서 SSR로 미리 html에 추가해서 SEO를 좋게 할 수 있다.

export const getServerSideProps: GetServerSideProps = async (context) => {
  const params = context.query.params;
  return {
    props: {
      params,
    },
  };
};

❗️ context를 바로 props로 return하는건 안되고 위처럼 params로 context.query.params를 변수로 받아온 뒤에 return 해야 한다.

받아오는건 아까처럼 받아오면 된다.

css

강의에서 module을 이용한 css, inline style, styled jsx를 알려줬는데

나도 css in js를 선호하기 때문에 styled jsx가 좋았다.

아래처럼 마지막에 쓰면 되고 className은 .이름 이렇게 설정해서 css를 사용하면 된다.

<div>
	<style jsx>{`
		div {
            color: blue;
          }
    `}</style>
</div>

next.config.js

프로젝트를 생성하면 이 파일이 있는데 여기서는
redirect, rewrite 설정을 할 수 있다.

redirects

원래 react에서는 백엔드에게 맡기던 작업인데

Next는 이 기능이 있었다.

async redirects() {
    return [
      {
        source: "/old-page/:path*",
        destination: "/new-page/:path*",
        permanent: false,
      },
    ];
  },

위처럼 예전 블로그에 접속했을때 최신 블로그로 리다이렉트 시켜줄 수 있다.

📌 permanent 옵션은 공식문서를 읽어보니 true/false에 따라 http status code 를 307이나 308로 준다고 한다

rewrites

api 로직을 짜다보면 api주소에 key를 넣어야 하는 경우가 있는데

그대로 api호출을 하면 누군가 내 key를 가져가서 막 쓸 수 있기 때문에 좋지 않다.

그럴때 rewrites로 api 주소를 내가 원하는걸로 덮어 쓸 수 있다.


const API_KEY = process.env.API_KEY;


const nextConfig = {
  async rewrites() {
    return [
      {
        source: "/api/movies",
        destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`,
      },
      {
        source: "/api/movies/:id",
        destination: `https://api.themoviedb.org/3/movie/:id?api_key=${API_KEY}`,
      },
    ];
  },
};

위처럼 설정하면

 fetch(`http://localhost:3000/api/movies`)

처럼 호출하면 위에서 설정한 destination으로 호출한다.

👍 React랑 문법도 같고 더 편한 느낌이라 다음 프로젝트에서는 꼭 사용해 봐야겠다

내 github 코드

출처: https://nomadcoders.co/nextjs-fundamentals/lobby

0개의 댓글