React - 화면이 mount 된 후 useEffect로 api 통신을 진행하기 때문에 통신이 느리다.
Next.js - 사전렌더링을 통해 접속 요청이 온 후 api 통신이 완료된 화면을 받기 때문에 속도가 빠르다
'
하지만 api통신의 데이터가 많을 경우 초기 로딩 속도가 너무 느릴 수 있다. 그럴때 Next.js는 Build Time에 사전렌더링을 하게 만들 수 있다.(npm run build 할 때) 이것을 SSG라고 한다(정적사이트생성)
// 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,
}
};
}
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가 반드시 있다고 가정하고 접근
}