Next js와 CRA의 차이점

hyeok·2022년 3월 6일
0

가장 큰 근본적 차이는 CRA는 클라이언트 사이드, Next js는 서버사이드 랜더링이라는 점이다.

CRA의 단점은 아래와 같다.

  1. flickering이 있다.

client 사이드의 경우, 처음 화면에서 서버에서 가져오는 정보로 다시 화면을 재구성하게 되는데 이 때 처음 가져올 때랑 refresh할 때마다 flickering (깜박임)과 같은 현상이 일어난다. 개발자는 이 문제를 해결하기 위해 cache를 사용해야하는 등 다양한 방법을 강구해야한다.

  1. SEO가 어렵다.

SEO엔진이 CRA사이트의 경우엔 텅빈 html돔만 보게된다. 이는 SEO가 불가능하게 만든다.
물론 이를 극복하기 위해 meta 태그를 중간중간 넣는 방법이 있긴하다. 허나 페이지마다 이 태그 설정을 해야하는데 이는 개발자를 귀찮게 한다.

Next js는 서버사이드 랜더링으로 이를 모두 해결한다. 그리고 편리한 장점들이 더 있다.

  1. pre-rendering
    미리 서버에서 랜더링해서 클라이언트에 넘겨준다. 그렇기 때문에 flickering도 없고 SEO 에도 좋다.

  2. file-based routing
    CRA와 같은 경우엔 router를 관리해야한다. 헌데 Next js는 파일 구성으로 이 라우팅을 간단하게 해결한다.

이걸 보면 news/something 라우팅이랑 news/1, news/2와 같은 파라미터가진 라우팅을 파일 구조로 해결한다. 코드도 덜 쓰고 서비스의 구조를 이해하기에도 직관적이다.

  1. 서버와 데이터 베이스와의 결합성
    서버사이드 랜더링이다 보니 nodejs 로직과 데이터베이스를 활용하는데 용이하다. 특히 auth 관리하는 데 편리하다.

아래는 api 폴더 내부의 핸들러이다.

// /api/new-meetup
// POST /api/new-meetup

async function handler(req, res) {
  if (req.method === 'POST') {
    const data = req.body;

    const client = await MongoClient.connect(
      'url'
    );
    const db = client.db();

    const meetupsCollection = db.collection('meetups');

    const result = await meetupsCollection.insertOne(data);

    client.close();

    res.status(201).json({ message: 'Meetup inserted!' });
  }
}

export default handler;

node js 사용해본 사람이라면 req.body, res.status와 같은 게 익숙할 것이다. next js에서 api를 제작해서 서비스 내부에서 사용이 가능하다.

그리고 CRA와 같은 경우엔 useEffect 부분에 비동기 서버 부분을 처리한다. 그래서 서버 api부분과 돔을 구현할때 사용되는 로직이 혼재되어 있다. 그런데 next js는 두가지 방식으로 따로 서버에서 처리해서 정보를 가져온 후 prerendering을 진행한다.

getStaticProps 방법

// posts will be populated at build time by getStaticProps()
function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries.
export async function getStaticProps() {
  // Call an external API endpoint to get posts.
  // You can use any data fetching library
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // By returning { props: { posts } }, the Blog component
  // will receive `posts` as a prop at build time
  return {
    props: {
      posts,
    },
    revalidate: 10,
  }
}

export default Blog

빌드할 때 실행된다. 서버사이드에서 데이터를 받은 뒤 page에 props로 내린다. useEffect로 따로 받을 필요가 없다. useEffect 디펜던시 때문에 스트레스 받던거 생각하면 아주 편리하다.

getServerSideProps 방법

function Page({ data }) {
  // Render data...
}

// This gets called on every request
export async function getServerSideProps(context) {
  // Fetch data from external API
  const req = context.req;
  
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  // Pass data to the page via props
  return { props: { data } }
}

export default Page

GetServersidProps는 request가 올 때마다 작동,
req, res 등을 사용할 수 있어 auth 관련된 로직을 관리하는 데 편하다.
모든 request때마다 새로 받아온다고 보면 된다.

단점은 getStaticProps는 캐쉬가 되어서 한번 받아오면 되는데 getserversideprops는 매번 다시 받아와야 한다.

위의 내용만 봐도 기존 CRA 방식과는 완전히 다르다. useEffect로 비동기 처리를 의존하던 때보다 훨씬 nextjs가 체계적이고 side effect를 줄일 수 있어 보인다.

profile
내가 만든 소프트웨어가 사람들을 즐겁게 할 수 있기 바라는 개발자

0개의 댓글