[Next] Next.js 기본 개념과 React.js와의 차이

Janet·2022년 8월 18일
1

Next.js

목록 보기
1/1

About the NextJS

  • NextJS Project 생성: npx create-next-app@latest
  • Typescript를 사용할 경우: npx create-next-app@latest --typescript

  • 개발용 서버 실행: npm run dev


0. React.js와 Next.js의 차이?

  • React.js는 라이브러리이고, Next.js는 프레임워크라고 할 수 있다.
  • 또한 React.js는 CSR(Client Side Rendering)을 하고, Next.js는 SSR(Server Side Rendering)을 한다.

1. Library와 Framework의 차이?

  • library: 필요한 라이브러리를 불러와 개발자가 자유롭게 개발에 사용 (React.js는 개발자가 원할 때 부르고 사용하는 라이브러리이다.)
  • framework: 특정한 규칙을 따라야만 정상 작동. 개발자가 코드를 특정한 곳에 넣으면 framework가 그 코드를 부르는 형태

2. create-react-app과 create-next-app의 차이점?

  • 위와 같은 기능들은 바로 create-next-app의 장점이 된다. create-react-app을 사용했다면 React router DOM을 다운받고 설정하고, Router를 만들어 Route를 설계하고 component를 import하고 render 등등 여러가지 과정이 필요할 것이다.
  • create-react-app은 client-side-render를 하는 앱을 만든다.
    • client-side rendering 과정: 브라우저가 HTML을 가져올 때 비어있는 상태 즉, 비어있는 div(root)로 가져옴 > 브라우저가 모든 자바스크립트를 요청 > 브라우저가 자바스크립트와 react.js를 실행시킴 > client-side의 자바스크립트가 UI를 만들어 유저에게 보여줌
    • 그렇기에, 유저의 네트워크 속도가 매우 느리거나하면 앱 화면은 비어있는 흰 화면만 보여지게 된다.
  • 그러나 next.js는 소스코드에 차이가 있다. 소스코드 안에 HTML이 남아있는 상태로 렌더링되기에 유저의 네트워크 속도가 매우 느리거나 혹여나 자바스크립트가 비활성화 되어있는 상태라고해도 api등으로부터 가져오는 데이터가 로딩되는 데에는 시간이 걸리겠지만 유저는 최소한으로 빈 화면이 아닌 HTML은 화면에 렌더링되는 것을 볼 수 있다.
  • Hydration이란? react.js를 프론트엔드 안에서 실행하는 것으로, 유저가 페이지를 열면 HTML이 화면에 렌더링됨 > react.js가 client-side로 전송. 이후 유저가 앱 화면을 볼 수 있게 된다. 반면, next.js는 react.js를 백엔드에서 동작시켜 페이지를 미리 만든다. 그러면 자바스크립트와 react.js가 아직 로딩되지 않았더라도 next.js는 HTML을 페이지의 소스코드에 넣어주고 이를 통해 유저는 콘텐츠를 미리 볼 수 있게된다.

3. next.js는 'pages'폴더 안에 react.js파일을 생성하면 해당 파일명을 경로로 컴포넌트를 자동적으로 페이지화하여 생성해준다.

  • 예시: 만약 pages 폴더 안에 intro.js파일을 생성 후, 파일 내에 export default 코드를 입력했다면 http://localhost:3000/intro 경로로 접속할 수 있다. (파일 이름으로 url이 생성됨)
  • pages 폴더 내부의 intro.js 파일은 home과 같은 개념이라 파일명이 아닌 http://localhost:3000/ 로 접속할 수 있다.
  • cf. Next.js에서는 JSX를 사용한다면 React.js를 import하지 않아도 된다.
  • 만약 /musics/list 라는 url에 접속하고 싶다면 pages폴더 내부에 musics폴더를 생성 > list.js파일을 생성해주면 해당 컴포넌트는 자동적으로 페이지화 된다. 또한 /musics 경로로 이동하고 싶다면 musics 폴더 안에 index.js를 생성해주면 해당 컴포넌트는 /musics로 접속 가능하다.
  • 또한, musics/100과 같이 url끝에 변수명으로 접속하길 원한다면 pages > musics 폴더에 [파일명].js 형식으로 파일을 생성해주면 된다. []로 감싸야함.

4. next.js에서 Link를 통한 페이지간의 이동 방법

  • next.js는 react.js처럼 anchor 태그가 아닌 link로 페이지 이동하기를 권장한다. a 태그를 이용해서도 페이지 이동 기능은 정상 작동하지만 이동할 때마다 페이지 전체를 re-fresh하여 렌더링하는 비효율적인 동작을 통하기 때문이다.

anchor 태그를 이용한 페이지 이동

export default function NavBar() {
    return (
        <nav>
            <a href="/">Home</a>
            <a href="/intro">Intro</a>
        </nav>
    )
}

Link를 이용한 페이지 이동

import Link from "next/link";
export default function NavBar() {
    return (
        <nav>
            <Link href="/">
                <a>Home</a>
            </Link>
            <Link href="/intro">
                <a>Intro</a>
            </Link>
        </nav>
    )
}

5. Style 적용 방법

  1. style.module.css 파일을 import하여 적용
import Link from "next/link";
import { useRouter } from "next/router";
import styles from "./NavBar.module.css";

export default function NavBar() {
    const router = useRouter();
    // useRouter를 변수로 선언
    return (
        <nav>
            <Link href="/">
                <a className={router.pathname === "/" ? styles.link : ""}>Home</a>
                {/* router.pathname은 url을 의미, 또한 a태그에 스타일 적용 */}
            </Link>
            <Link href="/intro">
                <a className={router.pathname === "/intro" ? styles.link : ""}>Intro</a>
            </Link>
        </nav>
    )
}
  1. style jsx 을 통한 적용 방법

    해당 컴포넌트에만 style을 적용하고 싶을 때 편리하다.

import Link from "next/link";
import { useRouter } from "next/router";

export default function NavBar() {
    const router = useRouter();
    // useRouter를 변수로 선언
    return (
        <nav>
            <Link href="/">
                <a className="aa">Home</a>
                {/* router.pathname은 url을 의미, 또한 a태그에 스타일 적용 */}
            </Link>
            <Link href="/intro">
                <a className="aa">Intro</a>
            </Link>
            <style jsx>{`
                nav {
                    background-color: blue;
                }
                a {
                    text-decoration: none;
                }
                .aa {
                    color: orange;
                }
            `}</style>
        </nav>
    )
}
  1. Style을 전역으로 적용하고 싶을 때

    _app.js에 global 스타일을 적용하면 하위 컴포넌트들에 모두 적용된다. 여기서 _app.js는 앱이 실행될 때, 가장 먼저 실행되는 상위 파일로 하위 컴포넌트를 관리하는 총괄 파일이다. 또한 _app.js에선 module.css가 아닌 .css파일을 import해서 사용 가능하다.

import NavBar from "../components/NavBar";

export default function MyApp({ Component, pageProps }) {
    return (
        <div>
            <NavBar />
            <Component {...pageProps} />
            <style jsx global>{`
                a {
                    text-decoration: none;
                }
                .aa {
                    color: orange;
                }
            `}</style>
        </div>
    )
}

6. 개인의 API key 숨기기 - redirects & rewrites

  • 퍼블리싱 혹은 git hub 업로드 과정에서 개인이 부여받은 api key를 숨기지 않는다면 타인에게 남용될 가능성이 있기에 이를 숨기는 방법 또한 존재한다.

    1. Redirects: /contact/1004 로 접속 -> /new-contact/1004 로 자동 이동

    2. Rewrites: Redirects와 Rewrites의 차이점: Redirect는 유저가 변경되는 url을 육안으로 확인 가능하지만, Rewrite의 경우 변경된 url을 숨긴다. (next.js가 request를 masking 해줌)

    3. API key를 보안화하는 방법으로 .env 파일을 생성하여 해당 파일에 api key를 따로 저장하고 .gitignore.env 파일을 등록하여 업로드 시 제외되도록 한다.

    4. 또 다른 방법으로는, getSeverSideProps 함수를 이용하는 것으로, 이 함수는 클라이언트가 아닌 서버쪽에서만 동작하기에, 이를 통해 백엔드 쪽에 API Key를 숨기는 것도 가능하다.

// next.config.js 파일

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
}
const API_KEY = process.env.API_KEY;
// API key를 .env 파일에 담아 저장해놓고 불러온다.
// 또한 .env 파일은 .gitignore 파일에 업로드 제외 파일로 등록하여 해당 파일의 정보를 개발자만 확인할 수 있도록 보안화한다.

module.exports = {
  nextConfig,
  async redirects() {
    return [
      {
        source: "/contact/:path*",
        destination: "/new-contact/:path*",
        permanent: false,
      },
    ];
  },
// <Redirects> source: 유저가 접속하는 url, destination: source의 url로 접속하면 destination의 url로 자동 이동됨
// destination은 외부 url 어느 곳으로든 redirect 시켜줌
// url 끝에 ":path*"를 붙이면 path도 알아서 matching 시켜준다.
// *를 붙이면 url끝에 추가적으로 뭐가 붙든 매칭시켜준다.
  async rewrites() {
    return [
      {
        source: "/api/movies",
        destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}&language=en-US&page=1`
      }
  ];

  }
};
// <Rewrites> 유저가 source url로 접속하면 destination url으로 자동 이동되지만, 유저는 destination의 url을 볼 수 없다. 유저에겐 source url만 보임

7. getSeverSideProps 함수

  • getSeverSideProps 함수를 이용하여 서버 즉, Back에서 동작할 코드를 넣을 수 있다.
profile
😸

0개의 댓글