다시 쓰는 React Next.js #2

YEZI🎐·2023년 3월 27일
1

React

목록 보기
31/46

Next.js 다양한 기능

layout 패턴

components 폴더에 Layout.js 만들어 NavBer, Header 등 공통으로 사용하는 것을 넣는다.
공통으로 사용하는 것을 _app.js에 작성해도 되지만,
대중적으로 _app.js를 크게 하기보단 Layout.js에 넣고 _app.js는 간단하게 사용한다.

// Layout.js
import NavBer from './NavBar';

export default function Layout({ children }) {
  return (
    <>
      <NavBar />
      <div>{children}</div>
    </>
  );
}
// _app.js
import Layout from '@/components/Layout';

export default function App({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

Next.js는 head 같이 자주 사용하는 기능의 패키지를 제공한다.
head 컴포넌트 안에 기존 html의 <head>에 작성했던 것 처럼 <meta>,<title> 같은 것을 작성한다.

import Head from 'next/head';

export default function Seo({ title }) {
  return (
    <Head>
      <title>{title} | Next Movies</title>
    </Head>
  );
}

public

public 폴더에 public 파일들을 불러와 사용할 때
../public/어찌구.jpg로 불러오지 않고 /어찌구/.jpg로 바로 pulic 파일을 불러올 수 있다.

redirects

next.config.js에 들어가 redirects 옵션을 작성한다.(적용 후 서버 재시작해야 함)
source url 로 접속 시 destination으로 보낸다.
source url에서 바뀌는 게 destination url로 바뀌는 것이 보이며, 유저도 url이 바뀌었다는 것을 알 수 있다.

const nextConfig = {
  reactStrictMode: true,
  /* 이 부분 ↓ */
  async redirects() {
    return [
      {
        source: '/about',	// 들어간 곳
        destination: '/',	// 보낼 곳 (외부 사이트도 가능 )
        permanent: false,	// 영구적인지 아닌지에 따라 브라우저나 검색엔진이 
        					// 이 정보를 기억할지 말지 여부 결정
      },
      {
        source: '/old/:path',	// :path : 나머지 경로
        destination: '/new/:path',	// :path : 입력된 나머지 경로
        // :path* : 나머지 경로 전체(source, destination 둘 다 작성해야 함)
        permanent: false,
      },
    ];
  }
}

rewrites

next.config.js에 들어가 rewrites 옵션을 작성한다.(적용 후 서버 재시작해야 함)
source url 로 접속 시 destination으로 보낸다.
source url이 바뀌지 않고 유지되지만 destination url으로 설정된 페이지가 보이며, 유저는 url이 바뀌었다는 것을 알 수 없다.

const nextConfig = {
  reactStrictMode: true,
  /* 이 부분 ↓ */
  async rewrites() {
    return [
      {
        source: '/about',	// 들어간 곳
        destination: '/',	// 보여질 곳
        permanent: false,	// 영구적인지 아닌지에 따라 브라우저나 검색엔진이 
        					// 이 정보를 기억할지 말지 여부 결정
      },
      {
        source: '/api/movies',	/* 이런 식으로 작성하여 API_KEY를 숨길 수 있다*/
        destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`,
      },
      {
        source: '/api/movies/:id',	// :id 동적 url
        destination: `https://api.themoviedb.org/3/movie/:id?api_key=${API_KEY}`,
        // source에서 :id라고 했으면 destination도 동일하게 작성해야 함 명칭 동일하게
      },
    ];
  }
}

getServerSideProps

getServerSideProps는 server쪽(백엔드)에서만 작동하는 function이다.

  • html에 데이터를 포함시키고 싶거나, 페이지가 유저에게 보여지기 전에 props를 받아야 하는
    컴포넌트 파일에 getServerSideProps를 export 시켜 사용한다.
  • getServerSideProps는 object를 return 하며 return 값은 props로써 page에게 주게 된다.
// async는 await 사용해서 썼을 뿐, 원래는 안 써도 됨
// getServerSideProps 내부 작성되는 코드는 다 server쪽(백엔드)에서만 작동
export async function getServerSideProps(){
  const { results } = await (await fetch(`http://localhost:3000/api/movies`)).json();
  return {
    // props라는 키를 갖고 원하는 데이터를 넘겨줄 수 있음
    props: { results },
  };
}
// 이런 식으로 return을 props로 받아서 사용할 수 있음
export default function Home({ results }) {}

getServerSideProps는백엔드의 데이터를 fetch하고 결과를 pre-render하여 html에 데이터 포함시킨다.
이러한 것이 SEO에는 유용하지만, 백엔드의 api작업이 끝날 때까지 아무 것도 안 보인다.
즉, 이러한 장단점이 있으니 니즈에 따라 유동적으로 사용하면 된다.

  • 데이터가 유효할 때 화면이 보여지고 싶다면 => getServerSideProps 사용
  • 로딩화면을 보여준 후 데이터를 받는고 싶다면 => getServerSideProps 사용 X

router

  • Link

    <Link href={`/movies/${movie.id}`}>{movie.original_title}</Link>
  • onClick

    const router = useRouter();
    const onClick = (id) => {
     router.push(`/movies/${id}`);
    };
    
    <div onClick={() => onClick(movie.id)}></div>
    // form 작성 후 페이지 이동하는 경우 등에서 사용할 수 있음

Dynamic Routes

page 폴더에 안에 product 폴더 생성 시, product 폴더 안에 있는 index.js는 product 경로의 기본 페이지가 된다.
product 하위 경로에 동적인 경로가 필요하다면, [변수명].js으로 폴더 안에 생성한다.

catch-all URL

  • catch-all URL : URL을 전부 캐치함, [...변수명].js

[변수명].js[...변수명].js로 바꾸면 모든 path를 잡을 수 있다.

앞서 말한 product 폴더로 예를 들자면,
pages/product/[...productid].js 라는 파일은 '/product/a' 이라는 url path와 매칭되며,
/product/a/b,/product/a/b/c와 같이 뒤에 추가로 붙는 path도 잡을 수 있다는 것이다.

url로 state 넘기기

아래 소스에서 query의 값으로 state를 넘길 수 있다.

const onClick = (id) => {
  router.push(
    {
      pathname: `/movies/${id}`,
      query: { title: 'hello' },	// ?title=hello
    },
    `/movies/${id}`	// query를 안보이게 함
  );
};

이렇게 state를 넘겼을 때,
자식 컴포넌트에는 그 값이 없고 부모 컴포넌트에게 state를 받은것 이기 때문에
자식으로 바로 접근하거나 자식 페이지에서 새로고침 시 state를 사용할 수 없어 에러가 난다.

404

page 폴더에 404.js만 생성해주면 된다.


++ API KEY 숨기기

개인 key는 github에 커밋 시 개인 정보 노출 위험이 있어 .env or .env.local 파일을 만들어 .env or .env.local파일에 변수로 지정해두어야 한다.
(파일 추가 후 .gitignore 에 파일명도 추가해야 함)

  • 변수 선언(.env) : API_KEY = 개인 API Key
  • 사용시 : apiKey : process.env.API_KEY,

이때, CRA 에서는 변수에 REACT_APP_를 붙여줘야 사용할 수 있었는데
Next에서는 NEXT_PUBLIC_을 변수 앞에 붙여줘야 사용할 수 있다.

  • CRA : REACT_APP_API_KEY = 개인 API Key, process.env.REACT_APP_API_KEY
  • Next : NEXT_PUBLIC_API_KEY = 개인 API Key, process.env.NEXT_PUBLIC_API_KEY
profile
까먹지마도토도토잠보🐘

0개의 댓글