Next.js] SSR(서버사이드 렌더링)/getServerSideProps/ context

짱효·2024년 3월 14일
0

Next.js

목록 보기
3/28








이미 랜더링된 html을 화면에 렌더링 하기때문에 빠르다.

동작은 불가능함.
그래서 javascript Bundle을 보내줌


이제는 html요소에 javascript 코드가 단비 내리듯 서로 연결

SSR은 이렇게 동작한다!


SSR 적용하기(1)


각각 페이지 별로 다른 렌더링 적용가능

export default function Home({ name }) {
  return <div>{name}</div>;
}
//SSR 방식으로 된다
export const getServerSideProps = async () => {
  // SSR을 위해 서버측에서 페이지 컴포넌트에게 전달할 데이터를 설정하는 함수

  return {
    //?무조건 객체로 설정하기
    props: {
      name: "KOREA",
    },
  };
};
  • getServerSideProps함수는 Home컴포넌트에게 데이터를 props로 넘겨주기위한 역할을 하는 함수
  • 오직 서버에서만 실행가능

  1. getServerSideProps함수 SSR을 위한 함수
  2. 넥스트 서버와 브라우저
  3. 브라우저가 인덱스 페이지에 가기위해 '/'를보낸다
  4. 맨처음 getServerSideProps함수를 실행한다.
  5. 인덱스 페이지에 필요한게 뭔지 함수안에서 계산을한다.props를 포함하는 객체로 반환한다.
  6. 페이지를 렌더링하기위해서 HOME 컴포넌트를 호출
  7. HOME의 Props에 getServerSideProps함수 객체의 값이 전달된다.
  8. 컴포넌트가 html 로 되고 브라우저에 전달된다.

컴포넌트가 html로 잘 변경됐는지 확인방법

  1. 소스 코드보기
  2. 네트워크에서 보기

주의

getServerSideProps함수는 서버측에서만 실행됨.

서버에서만 실행되서 브라우저의 console에 안나옴

  • 터미널에서 콘솔 확인 가능

  • window는 브라우저여서

    오류가 발생한다.

  • home 컴포넌트 안에서도 에러발생

  • 홈 컴포넌트 서버에서 랜더링되기위해 한번 실행되고
    브라우저에서 수화과정이 끝난이후에
    한번더 마운트되서 실행되서
    브라우저에서도 터미널에서도 콘솔확인 가능.

  • 콘솔 브라우저에서만 보고싶어!!

[최종코드]

export default function Home({ name }) {
  console.log("Home");
  return <div>{name}</div>;
}
//SSR 방식으로 된다
export const getServerSideProps = async () => {
  // SSR을 위해 서버측에서 페이지 컴포넌트에게 전달할 데이터를 설정하는 함수

  //서버에서만 실행되서 브라우저의 console에 안나옴
  console.log("getServerSideProps Called");
  return {
    //?무조건 객체로 설정하기
    props: {
      name: "KOREA",
    },
  };
};

SSR 적용하기(2)

  • 진짜 필요한 데이터 가져오기

  • 넥스트에서 기본 제공 안함
    import axios from "axios";

  • 데이터 API 파일

//넥스트에서 기본 제공 안함
import axios from "axios";

export async function fetchCountries() {
  try {
    const response = await axios.get("https://naras-api.vercel.app/all");
    return response.data;
  } catch (e) {
    return [];
  }
}

export async function fetchSearchResults(q) {
  try {
    const response = await axios.get(`
  https://naras-api.vercel.app/search?q=${q}
  `);

    return response.data;
  } catch (e) {
    return [];
  }
}

export async function fetchCountry(code) {
  try {
    const response = await axios.get(
      `https://naras-api.vercel.app/code/${code}`
    );
    return response.data;
  } catch (e) {
    return null;
  }
}
  • 데이터 가져오기
import { fetchCountries } from "@/api";

export default function Home({ countries }) {
  return (
    <div>
      {countries.map((country) => (
        <div key={country.code}>{country.commonName}</div>
      ))}
    </div>
  );
}
//SSR 방식으로 된다
export const getServerSideProps = async () => {
  // API 호출
  const countries = await fetchCountries();
  return {
    //?무조건 객체로 설정하기
    props: {
      countries,
    },
  };
};



서버측에서 만들어서 한방에 보여줌.
[next,js]

[REACT]

[search 코드]

http://localhost:3000/search?q=korea q값 가져오기

const { q } = context.query;

import { fetchSearchResults } from "@/api";
import SubLayout from "@/components/SubLayout";

export default function Search({ countries }) {
  return (
    <div>
      {countries.map((country) => (
        <div key={country.code}>{country.commonName}</div>
      ))}
    </div>
  );
}
//* 위에 함수는 객체로도 쓸 수 있어서 밑에처럼 사용가능
Search.Layout = SubLayout;

export const getServerSideProps = async (context) => {
  // 1. 검색 결과 API 호출
  // 2. Props 리턴

  const { q } = context.query;

  let countries = [];
  if (q) {
    countries = await fetchSearchResults(q);
  }

  return {
    props: {
      countries,
    },
  };
};

[[code].js 코드]

  • http://localhost:3000/country/kor /kor 값 가져오기

const { code } = context.params;

//라우터의 모든 기능이 다들어있다.
import { fetchCountry } from "@/api";
import SubLayout from "@/components/SubLayout";
import { useRouter } from "next/router";

export default function Country({ country }) {
  const router = useRouter();
  const { code } = router.query;
  //url 코드 값 가져오기

  return (
    <div>
      {country.commonName} {country.officialName}
    </div>
  );
}

Country.Layout = SubLayout;

//? context: url 정보를 가져오는 context 객체
export const getServerSideProps = async (context) => {
  const { code } = context.params;
  let country = null;
  if (code) {
    country = await fetchCountry(code);
  }
  return {
    props: { country },
  };
};

데이터 가져오는 방법 2가지

  1. useRouter:리액트 훅, 수화과정이 끝나고 동작, 클라이언트에서 이용할려면 컴포넌트 내부에서 불러오기(CSR)
export default function Country({ country }) {
  //리액트 훅, 수화과정이 끝나고 동작, 클라이언트에서 이용할려면 컴포넌트 내부에서 불러오기
  💛const router = useRouter();
  //
  💛const { code } = router.query;
  //url 코드 값 가져오기

  return (
    <div>
      {country.commonName} {country.officialName}
    </div>
  );
}
  1. context :서버측에서 데이터를 패치하고싶으면 context에서 가져오면 된다.(SSR)
//? context: url 정보를 가져오는 context 객체
export const getServerSideProps = async (💛context) => {
  // 서버측에서 데이터를 패치하고싶으면 context에서 가져오면 된다.
  💛const { code } = context.params;
  let country = null;
  if (code) {
    country = await fetchCountry(code);
  }
  return {
    props: { country },
  };
};
profile
✨🌏확장해 나가는 프론트엔드 개발자입니다✏️

0개의 댓글