NEXTJS 시작하기

2023. 3. 8. 23:27·TECH

노마드코더 NextJS 를 보고 정리한 내용입니다.

 

NEXTJS 설치 

 npx create-next-app@latest

 

라이브러리와 프레임워크의 차이

라이브러리

원할때 사용할 수있다. 앱을 만드는데 자유도가 있다.

 

프레임워크

프레임워크가 정한 규칙을 지켜야한다. 

다른설정없이도 규칙만 지키면 동작한다. 커스텀이 제한된다. 

 

pages

nextjs 프로젝트 내 pages폴더에 파일을 넣으면 파일이름이 url로 들어간다. 

localhost:3000/aboout

 

CSR, SSR

CSR - Client Side Rendering

브라우저가 자바스크립트를 가져와서 UI를 만든다. 

네트워크가 느리면 화면이 늦게 노출 될 수있어서 로딩처리를 해야한다. 

 

소스보기를 하면 root dom을 확인할  수 있다.

<div id="root"></div>

 

SSR - Server Side Rendering

앱에있는 페이지들이 pre-rendering되는 것

유저가 페이지를 요청하면 서버에서 html을 내려준다. 

자바스크립트와 react.js가 로드되지 않아도 콘텐츠를 바로 확인할 수있다. 

 

장점: SEO 좋다. 

 

Routing

Link라는 앱 내에서 페이지를 네비게이트할 때 사용해야하는 특정 컴포넌트가 존재한다. 

// 기존에는 Link 태그안에 a태그를 넣어줘야했지만 
<Link href="/about">
  <a>about</a>
</Link>

// next13부터 a태그 안써준다. 
// 기존에는 Link내 a태그에 props를 내려줘야 적용이 되었지만 
// next13부터는 link에 내려줘도 된다.
<Link href="/about" style={{ border: '1px solid red' }}>
  about
</Link>

 

리액트처럼 react-router-dom 라이브러리를 설치하지 않아도
next는 다 내장되어있기 때문에 router를 사용할 수있다. 

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

const NavBar = () => {
  const router = useRouter();
  return <nav>
    <Link href="/" style={{color: router.pathname === '/' ? 'red': 'blue' }}>
      홈
    </Link>
    <Link href="/about" style={{color: router.pathname === '/about' ? 'red': 'blue' }}>
      about
    </Link>
  </nav>
}

export default NavBar;

 

 

module.css

module.css 을 사용할때 여러개의 클래스를 적용해야한다면
1. 백틱을 이용하는 방법

<Link href="/" className={`${styles.link} ${router.pathname === '/' ? styles.active : ''}`}>홈</Link>


2. array로 만들어 join하는 방법

<Link href="/about" className={[styles.link, router.pathname === '/about' ? styles.active : ''].join(" ")}>about</Link>

 

styled jsx   

nextJS 고유의방법
styled jsx는 컴포넌트안에서만 적용된다. 다른 컴포넌트에 적용되지 않는다.

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

const NavBar = () => {
  const router = useRouter();
  return <nav>
    <Link href="/" className={router.pathname === '/' ? 'active' : ''}>홈</Link>
    <Link href="/about" className={router.pathname === '/about' ? 'active' : ''}>about</Link>
    <style jsx>{`
        nav {
          background-color: tomato;
        }
        a {
          text-decoration: none;
        }
        .active {
          color: yellow;
        }
    `}</style>
  </nav>
}

export default NavBar;

 

글로벌 스타일 적용할 때 

모든컴포넌트의 root 컴포넌트에 글로벌 스타일 선언

<style jsx global>{`
  nav {
  	background-color: tomato;
  }
  a {
  	text-decoration: none;
  }
  .active {
  	color: yellow;
  }
`}</style>

 

_app.js

없어도 nextjs가 만들어서 잘 작동하게 해주지만 

커스텀 하고싶을때 pages/_app.js 파일을 만들어서 커스텀을 해준다. 

_app컴포넌트에서 아래의 코드들을 추가할 수 있다. 

- Google analytics
- 검색엔진 설정
- 스크립트 분석

 

_app.js에서 공통레이아웃을 설정할 수 있지만

공통레이아웃은 components/layout.js 파일을 만들어서 _app 컴포넌트를 children으로 받아서 사용한다. 

// pages/_app.js

// Component, pageProps는 next가 정해놓은 규칙
// Component에는 렌더링되는 컴포넌트가 들어간다. 
const App = ({ Component, pageProps }) => { 
  return <Component {...pageProps} />
}

export default App;

 

Head

next에서 head에 들어가는 속성(title, meta 등등...) 변경할수있는 컴포넌트 

 

nextJS의 멋진 점! 작은패키지를 별도 설치없이 사용할 수 있다는 점 

create-react-app으로 진행하는경우 react helmet이라는 패키지를 설치해서 사용해야하는데 

next는 기본내장 되어있다. 

import Head from 'next/head';
import NavBar from "@/components/NavBar";

const Index = () => {
  return (
    <div>
      <Head>
        <title>Home</title>
      </Head>
      <NavBar />
    </div>
  )
}

export default Index;

 

public

next.js를 이용하면 public파일을 쉽게 다룰수 있다.
public 파일을 public 디렉토리에 넣으면 된다.

<img src="/react-hooks.png" /> //경로만 입력해주면 된다.

 

redirect

next.config.js에 redirects 설정을 할 수있다.
외부경로로도 redirect할 수 있다.

경로가 변경된 경우 redirect를 시켜줄수있다.

 

permanent 속성관련 참고 
https://forlater.tistory.com/371

permanent: true - 영구적으로 url 변경되었으니, 추후에 바뀐url로 이용해달라는 것
permanent: false - 임시적으로 url 변경

// next.config.js
const nextConfig = {
  reactStrictMode: true,
  async redirects(){
    return [
      { 
        // contact로 접근하면 form으로 경로가 redirect된다. 외부경로로도 redirect할 수 있다.
        source: "/contact",
        destination: "/form",
        // permanent 영구적 리다이렉트, 임시적 리다이렉트
        permanent: false
      }
    ]
  }
}

module.exports = nextConfig

 


동적 경로를 redirect 하는경우

:path* "*"를 넣어주면 뒤에 모든 패스를 의미한다. 

// boards/111 redirect(0)
// boards/11/222 redirect(x)
{
  source: "/boards/:path", 
  destination: "https://www.naver.com",
  permanent: false
}


// boards/11/222 redirect(0)
{
  source: "/boards/:path*", 
  destination: "https://www.naver.com",
  permanent: false
}

 

rewrite

유저가 rewrite되기 전 url를 확인할 수 없다.
이것으로 API_KEY를 숨길수 있다.
url에 마스크를 씌워주는 역활

//next.config.js
const API_KEY = process.env.API_KEY;

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

module.exports = nextConfig
//.env
API_KEY=*****************************
// index.js
useEffect(() => {
  (async() => {
    // /api/movies써주면 https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}를 호출
    const {results} = await (await fetch('/api/movies')).json();
    setMovies(results)
  })()
}, []);

 

SSR

서버렌더링 할 수있는 getServerSideProps가 있다. 

getServerSideProps는 서버에서만 실행되는 코드, API키를 숨길 수도 있다. 

getServerSideProps 네이밍 변경은 안된다. 

getServerSideProps에서 return하는 객체는 _app.js에서 pageProps로 받는다. 

서버에서 data fetch를 하고 html을 그려주기때문에 모든데이터를 html에서 확인할 수 있다. 

// server에서 받은 movies props
const Index = ({ movies }) => {
  return (
    <div>
      {!movies && <div>Loading....</div>}
      <ul>
        {movies?.map((movie => <li key={movie.id}>{movie.original_title}</li>))}
      </ul>
    </div>
  )
}

//서버에서 돌아가는 코드
export async function getServerSideProps() {
  const {results} = await (await fetch('http://localhost:3000/api/movies')).json();

  // props키를 가진 object를 return
  // return하면 page컴포넌트의 props로 받을 수 있다.
  return {
    props: {
      movies: results
    }
  }
}

export default Index;

 

getServerSideProps는 context(url 정보)를 받아올 수 있다. 

export async function getServerSideProps(ctx) {
  console.log(ctx);

  return {
    props: {}
  }
}

 

중첩라우팅

movies/[id].js 대괄호를 써서 파일명을 만들어주면 된다. 

대괄호 안에 들어간 값을 router로 받을 수 있다.

 

여러 파라미터가 들어가는 경우 

[...id].js 파일명으로 만들면 된다. 

 

/movies/631842/11/22로 접근한 경우

url에 path가 array가 된다. 

 

라우터로 여러파라미터 보내기 

const onClick = (id, title) => {
  // router.push('전달하고싶은 real url', 'user에게 보여지는 url')
  router.push(
    {
      pathname: '/movies/${id}',
      query: {
      	id: id,
      	title: title,
      }
    },
    `/movies/${id}`
  );
}

// Link에서도 가능하다
<Link
  href={{
      pathname: '/movies/${id}',
      query: {
      	id: id,
      	title: title,
      }
    }}
  as={`/movies/${movie.id}`}
></Link>

 

as를 쓰지 않는경우 

 

as를 써서 보여주고 싶은 url 지정한 경우 

 

이동한 페이지에서 router 파라미터 확인

 

 

이동하려는 페이지 url에 영화타이틀과 같은 정보를 넣어주면 seo측면에서 더 유리할 수 있다. 

router.query를 사용하는게 아니라 url path로 넣어준다. 

ex) movies/영화이름/111 

 

링크를 클릭하는게 아니라 url로 바로접근하는경우

상세페이지에서 pre-render로 서버에서는 router.query.params가 배열인것을 확인할 수 없어서 

없는경우 빈배열로 초기화를 시켜줘야한다. 

 

getServerSideProps에 context를 사용해서 url정보를 가져올 수 있다.

fetch를 위한것이 아닌 더 빠른 데이터 접근을 위해서 context로 접근해서 사용할 수있다. 

context로 가져온 정보를 컴포넌트 props로 전달하면 

html파일에도 정보가 들어가있는 것을 확인할 수있다. 

'TECH' 카테고리의 다른 글

HTTP 프로토콜  (0) 2023.04.17
HTTP 상태코드  (0) 2023.04.17
React Hooks  (0) 2023.03.08
React 기본개념  (0) 2023.03.08
Framer Motion 애니메이션 라이브러리  (0) 2023.03.06
'TECH' 카테고리의 다른 글
  • HTTP 프로토콜
  • HTTP 상태코드
  • React Hooks
  • React 기본개념
ssund
ssund
  • ssund
    ssund의 기술블로그
    ssund
  • 전체
    오늘
    어제
    • 분류 전체보기 (73)
      • TECH (22)
      • NOTE (40)
      • DAILY (7)
      • javascript (1)
      • 알고리즘 (0)
  • 블로그 메뉴

    • 홈
    • TECH
    • NOTE
    • DAILY
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    react state management
    JavaScript
    theme-provider
    함수와 메서드차이
    Array.sort()
    reduxtoolkit
    d.ts
    React
    타입스크립트
    styled-components
    커머스프로젝트
    slidesPerGroup
    redux
    global-style
    reat-head
    배열요소순서
    웹브라우저구성
    call signatures
    TypeScript
    git배포
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
ssund
NEXTJS 시작하기
상단으로

티스토리툴바