[Next.js] Next.js에서 CSR 구현하기

Jane·2023년 8월 23일
3

Next.js

목록 보기
7/12
post-thumbnail

🧐 Next.js에서의 CSR, 왜 사용할까?

  • React의 CSR에서, 브라우저는 최소한의 HTML 파일과 페이지에 필요한 최소한의 JS 코드만을 다운로드 받는다.
  • 그 후 클라이언트는 JS를 사용하여 DOM을 업데이트하고, 페이지를 렌더링한다.
  • 애플리케이션이 처음 로드되었을 때, 사용자는 그들이 전체 페이지를 보기 전에 약간의 지연을 겪게 된다.
    • 이는 모든 JS 코드가 다운로드 되어 파싱되고, 실행되기 전까지 페이지가 렌더링되지 않기 때문이다.
  • 대신 CSR 방식을 사용하는 경우 페이지가 처음 로드된 이후에 같은 웹 사이트 내 다른 페이지로의 이동이 다른 방식에 비해 일반적으로 더 빠르다.
    • 필요한 데이터만 fetching하면 되고, JS는 전체 페이지를 새로고침하지 않고도 페이지의 일부를 리렌더링할 수 있기 때문이다.
👩‍🏫 이제 Next.js에서 공식적으로 알려주는 두 가지 CSR 구현 방법을 알아봅시다!

🪄 useEffect() 사용하기

🌟 SSR 메소드 대신 useEffect() 훅을 페이지 내부에 사용한다.

import React, { useState, useEffect } from "react";

export function Page() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch("https://api.example.com/data");
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      setData(result);
    };

    fetchData().catch((e) => {
      // handle the error as needed
      console.error("An error occurred while fetching the data: ", e);
    });
  }, []);

  return <p>{data ? `Your data: ${data}` : "Loading..."}</p>;
}
  1. 컴포넌트는 Loading...을 보여주면서 렌더링 과정을 시작한다.
  2. 데이터가 fetch 되면, 컴포넌트는 리렌더링 되면서 데이터를 보여준다.

💼 Data-Fetching 라이브러리 사용하기

  • 클라이언트가 데이터를 fetch할 수 있도록 SWR과 같은 data-fetching 라이브러리를 사용한다.
👩‍🏫 공식적으로 권장되는 방식입니다!

SWR

  • Stale-While-Revalidate
  • 데이터를 가져오기 위한 React 훅 함수
  • Vercel에서 만든, 데이터를 가져오기 위한 모듈이다.
  • 백그라운드에서 캐시에 대한 fetch 요청(revalidate)을 하는 동안 신선하지 않은 상태의 캐시 데이터를 사용하여 화면을 렌더링하다가 최종적으로는 최신화된 신선한 데이터를 반환한다.
  • 도중에 에러를 반환하더라도 기존 캐시 데이터를 사용할 수 있게 하여 불필요한 API Call과 렌더링을 최소화할 수 있게 한다.
  • npm i swr로 설치하여 사용할 수 있다.

useSWR

import useSWR from "swr";

const fetcher = (url: string) => axios.get(url);

function Profile() {
  const { data, error, isLoading } = useSWR("/api/url", fetcher, {// option});

  if (error) return <div>failed to load</div>;
  if (isLoading) return <div>loading...</div>;
  return <div>hello {data.name}!</div>;
}
  • useSWR(key, fetcher)
    • key(string): 데이터의 고유한 식별자 (일반적으로 API URL)
    • fetcher(function): 데이터를 반환하는 비동기 함수 (axios, fetch 등)
  • 요청의 상태에 따라 {data, isLoading, error} 값을 반환한다.
    • data: 요청에 에러가 없는 경우 가져오는 데이터
    • error: 요청에 에러가 있는 경우 발생한 오류
  • 세 번째 인자인 option 객체에 revalidate, mutate, initialData 등의 값을 넣어줄 수 있다.

🌟 useSWR과 함께 Next.js에서 CSR 구현하기

import useSWR from "swr";

export function Page() {
  const { data, error, isLoading } = useSWR(
    "https://api.example.com/data",
    fetcher
  );

  if (error) return <p>Failed to load.</p>;
  if (isLoading) return <p>Loading...</p>;

  return <p>Your Data: {data}</p>;
}
  • Next.js 공식문서에서는 성능이나 캐싱, 낙관적 업데이트 등의 측면에서 data-fetching 라이브러리를 사용하는 것을 권장한다.
  • SWR은 자동으로 데이터를 캐싱하고 만약 데이터가 신선하지 않은 상태가 된다면 해당 데이터에 대해 revalidate를 진행한다.

🤔 어떻게 동작하나요?

  1. useSWR은 초기에 props로 넘어온 데이터를 SWR 캐시에 저장한다.
  2. SWR는 캐시 데이터가 있으므로, 컴포넌트 최초 렌더링 시 요청을 보내지 않는다.
  3. 대신 다른 화면을 갔다와서 다시 포커싱 되거나, 네트워가 끊겼다가 다시 복구되는 등의 상황 또는 사용자의 설정에 따라 원하는 순간에 revalidate 값을 설정하면 SWR은 데이터를 재요청한다.
  4. 만약 새로 불러온 값이 기존의 캐시 데이터와 같다면 따로 리렌더링을 발생시키지 않고, 다른 경우 리렌더링을 진행한다.

📢 그럼에도 잊지 말아야 할 것

  • 몇몇 검색 엔진의 크롤러들은 JS를 실행하지 못하여 CSR 방식을 사용할 경우 초기의 빈 화면이나 로딩 중인 상태만을 보게 될 수 있다.
  • 또한 사용자들은 그들이 전체 페이지를 보기 전 모든 JS 코드가 로드되고 실행되는 것을 기다려야 하므로 인터넷이나 기기의 연결이 다른 방식을 사용할 때보다 더 느리다고 생각할 수 있다.
  • Next.js는 CSR 뿐만 아니라 SSR, SSG 방식을 각 페이지의 필요에 따라 혼용할 수 있도록 만들어져 있으므로, 무조건 한 방식만을 채택하기 보다는 각 페이지에 적합한 방식이 무엇인지를 고민하여 사용하면 좋다!

🔎 References

참고 자료 모음
profile
An investment in knowledge pays the best interest🙃

0개의 댓글