MouseNext/PageRouter - 2. 사전 렌더링, SSR

CodeModel·2024년 11월 11일
0

MouseNext

목록 보기
2/11

사전렌더링

React - 화면이 mount 된 후 useEffect로 api 통신을 진행하기 때문에 통신이 느리다.
Next.js - 사전렌더링을 통해 접속 요청이 온 후 api 통신이 완료된 화면을 받기 때문에 속도가 빠르다


'

하지만 api통신의 데이터가 많을 경우 초기 로딩 속도가 너무 느릴 수 있다. 그럴때 Next.js는 Build Time에 사전렌더링을 하게 만들 수 있다.(npm run build 할 때) 이것을 SSG라고 한다(정적사이트생성)

Next의 사전 렌더링방식

  1. 서버사이드 렌더링 (SSR)
  • 가장 기본적인 사전 렌더링 방식
  • 요청이 들어올 때 마다 사전 렌더링을 진행한다
  1. 정적 사이트 생성 (SSG)
  • 빌드 타임에 미리 페이지를 사전 렌더링 해둔다.
  1. 증분 정적 재생성 (ISR)
  • SSG 방식으로 생성된 정적 페이지를 일정 시간을 주기로 다시 생성하는 기술

SSR

// Next.js에서 약속된 함수명이다. 그렇다면 이 페이지는 이제 SSR 방식으로 이루어지게된다.

// 1.localhost:3000/home 으로 들어온 후
// 2.getServerSideProps 함수를 실행해서 api 데이터를 가져온 후
// 3.Home 컴포넌트를 가져온다
export const getServerSideProps = () {
	// 컴포넌트보다 먼저 실행되어, 컴포넌트에 필요한 데이터를 가져온다
    // 해당 함수는 서버환경에서만 실행되기 때문에 콘솔 등이 넥스트의 서버 콘솔에 나온다.
  	const data = "hello";
  	const q = context.query.q; // context는 클라이언트의 모든 정보를 가지고 있는 Next의 문법이다.
  
  	// 프레임워크의 문법으로 return은 이 방식으로 해야한다
  	return {
    	props: {
          data,
        }
    };
};

export default fuction Home({
  data 
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
  	// Next를 사용할때는 이 컴포넌트도 서버를 한번 거치기 때문에
    // 클라이언트에서만 코드를 실행하고 싶다면 useEffect를 사용해야한다.
  	useEffect(()=>{
    	console.log(window)
    },[])
  	console.log(data) // hello가 잘 나온다
	return <div>SSR</div> 
}

비동기함수의 타입

lib 폴더 아래에
fetchBooks.ts 폴더를 만든 후 통신을 진행한다
이때 타입은 내가 통신한 데이터의 객체를 Promise<>로 만들어 제네릭으로 감싸준다.

// ?는 q 값이 undefind여도 문제없이 실행 가능하게 해준다
export default async finction fetchBooks(q?:string) : Promise<BookData[]> {
  let url = "http://server"
  
  if(q) {
  	url += `/search?q=${q}` // q가 있다면 book에서 검색한 값을 통신한다
  }
  
  try {
    const response = await fetch(url);
	if(!response.ok) {
      throw new Error();
    }
	return await response.json()
  } catch (err) {
    console.error(err);
    return []
}

비동기 동시 실행

비동기 실행 코드를 여러개 나열하면 직렬적으로 비동기를 실행하기 때문에 비동기마다 기다리게 된다. 이럴때 비동기코드를 병렬적으로 한번에 실행할 수 있다.

export const getServerSideProps = async () => {
  	// 기존 직렬 통신 방법
	const allBooks = await fetchBooks();
  	const recoBooks = await fetchRandomBooks();
 
    // 병렬 통신 방법
	// PromiseAll을 이용하여 비동기 통신을 한번에 진행한다.
	const [allBooks, recoBooks] = await Promise.all([
    	fetchBooks(),
        fetchRandomBooks(),
    ])
    
    // getServerSideProps의 return 문법..
    return {
      props: {
        allBooks,
        recoBooks,
      }
    };
}

getServerSideProps 클라이언트 정보 가져오기

export const getServerSideProps = async (context: GetServerSidePropsContext) {
  	const q = context.query.q; // context는 클라이언트의 모든 정보를 가지고 있는 Next의 문법이다.
  	const books = await fetchBooks(q as string); // 클라이언트 정보 전달
  	
  // 프레임워크의 문법으로 return은 이 방식으로 해야한다
  	return {
    	props: {books,}
    };
};

?? 와 ? 와 !

?? - null 병합 연산자
왼쪽이 null 또는 undefined일 때 오른쪽 값을 반환합니다. 아닐경우 왼쪽을 반환합니다.

const userName = null;
const displayName = userName ?? "Guest"; // userName이 null이므로 "Guest" 반환

? - 옵셔널 체이닝
접근하려는 값이 null 또는 undefined일 경우 에러를 던지지 않고, 대신 undefined를 반환합니다.

const user = { name: "Alice" };
console.log(user?.address?.city); // undefined (address가 없으므로 안전하게 undefined 반환)

!
컴파일러에게 이 값이 null이나 undefined가 아님을 확실하게 알려줄 때 사용합니다.만약 null이나 undefined이면 에러가 발생합니다.

function printUser(user: { name: string; age?: number }) {
  console.log(user.age!); // age가 반드시 있다고 가정하고 접근
}
profile
개발자가 되기 위한 일기

0개의 댓글