📄 Next.js
Vercel 사에서 개발한 React로 만드는 *SSR 프레임워크 로 풀스택 웹 애플리케이션을 지원한다.
*SSR 프레임워크에 관해서는 아래에서 설명하니 지금 몰라도 된다.
Next.js는 현재 React 프레임워크 중 1위이며, 깃허브 내 14번째로 큰 프로젝트라고 한다.
보다시피 현재 다양한 그리고 엄청난 기업들에서 Next.js로 웹사이트를 구축했다고 한다...!
React와 Next.js의 차이가 분명하다는 건 알았으나 구체적으론 몰랐다.
그래서 이번 기회에 니꼬쌤 Next.js 강의 들으면서 조금 정리해봤다.
(여기 정리한 내용도 모두 레퍼런스는 니꼬쌤 강의 ,,,)
Next.js에 아예 무지하다면 링크 걸어놓은 니꼬쌤 강의 꼭 추천한다 !!!!!!!
React는 (UI를 build하는데 사용하는) 라이브러리
Q. 라이브러리(library) 란 ?
❕ 공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것.
❕ 전체적인 틀이 아닌 하나의 기능만을 도구처럼 제공.
❕ 도구를 사용하는 주체는 나(개발자)로, 우리가 구조에 관한 모든 결정을 내림.
*library의 사전적 정의인 '도서관'에서 책 하나씩 빌리는 것처럼, 도구를 하나씩 빌려서 사용하는 것이라고 하면 이해하기 좀 쉬울 듯 !
즉, 우리가 라이브러리를 원하는 방식대로 사용하여 구축하고, 라이브러리는 우리를 위해 아무런 결정도 내리지 않는다.
Next.js는 React의 프레임워크
Q. 프레임워크(framework) 란 ?
❕ 일정한 형태를 가지고 다양한 형태의 결과물을 만드는 것.
❕ 하나의 기능이 아닌 전체적인 틀을 제공.
❕ 나(개발자)의 코드를 사용하여 우리를 위해 많은 일들을 대신 해줌.
*framework의 사전적 정의도 '뼈대'로, framework는 틀 그 자체 !
Next.js 에서는 Built-in Optimizations, Dynamic HTML Streaming, React Server Components 등등의 일들을 해준다고 한다.
즉, 우리가 프레임워크를 사용하려면 여기서 제시하는 규칙을 지켜야 하며, 규칙만 맞으면 나대신 구축해준다.
💡 정리하면, 라이브러리는 우리가 사용하고, 프레임워크는 우리의 코드를 사용한다 !
React와 Next.js의 가장 큰 차이점
그거슨 바로 CSR과 SSR
Q. 렌더링(rendering) 이란 ?
❕ 코드로 정의된 내용이 실제 브라우저 화면에 그려지는 과정.
CSR(Client Side Rendering) : 브라우저에서 렌더링 작업
즉, 브라우저가 JavaScript 파일을 다운로드하고 실행한 후에야 화면이 보인다.
(App(UI)을 실행시키려면 JavaScript를 활성화해야 함.)
SSR(Server Side Rendering) : 서버에서 렌더링 작업
즉, 서버에서 렌더링 작업을 하기 때문에 모든 컴포넌트와 페이지들은 (서버에서 렌더링된) HTML이 이미 존재하고, JavaScript 파일을 다운로드하지 않아도 UI는 이미 빌드되어 있다.
최초 애플리케이션의 UI 빌드에선 JavaScript에 의존하지 않는다.
💡 정리하면, SSR은 JavaScript가 없어도 실행이 되며, 브라우저는 즉시 화면에 표시할 수 있다. 그렇기에 초기 로딩 시간이 확연히 줄어들어 UX는 향상된다.
1. 복잡한 웹 애플리케이션을 구축하는 과정을 편리하게 만들어주는 도구.
2. 미리 작성된 코드와 필요한 기능을 제공.
3. 개발자가 처음부터 모든 것을 구현하는 데 소요되는 시간과 노력을 줄여줌.
Next.js는 실행할 때 app 폴더 안에 page 파일같이 특정 파일을 찾기 때문에 폴더와 파일 지정을 잘해주는 것이 필수이다 !
// app 폴더 안에 있어야 하는 파일들
app/layout.tsx
app/not-found.tsx
app/page.tsx
그리고 폴더명 지정이 잠재적으로 하나의 페이지가 될 수 있다는 것을 의미한다.
그러나 폴더 안의 직접적인 page 파일이 없는 폴더는 그저 경로의 일부분이다.
about-us, company, sales는 폴더명으로 페이지 경로가 되었고, sales 폴더 안에는 page 파일이 있기 때문에 없는 페이지가 아닌 유효한 페이지가 되었다 !
Q. 그렇다면 app 폴더 안에 다른 파일을 넣어도 되나?
❕ 된다. 왜냐하면 page 파일이 없다면 실제 경로에 포함되지도 않고 렌더링되지도 않아서 상관은 없다. 그저 url로 유효하지 않을 뿐이다 !
Next.js에서 네비게이션을 구현한다면 ?
<a href="..."></a>
태그가 아닌 <Link/>
컴포넌트를 사용해 구현할 수 있다.
<a/>
태그를 사용하면 브라우저의 네비게이션을 사용하게 되는데
우리는 프레임워크의 네비게이션을 사용해야한다 !
<Link/>
컴포넌트는 프레임워크 네비게이션을 가능하게 한다.
💡 이렇게하면, 클라이언트 측 라우팅을 사용하여 페이지 간의 전환을 처리하므로 페이지가 새로 고쳐지지 않는다.
아래는 예시 코드이다.
// navigation.tsx
import Link from "next/link";
import { usePathname } from "next/navigation";
export default function Navigation() {
const path = usePathname();
console.log(path); // '/' or '/about-us'
return (
<nav>
<ul>
<li>
<Link href="/">Home</Link>
</li>
<li>
<Link href="/about-us">About Us</Link>
</li>
</ul>
</nav>
);
}
usePathname()을 사용하면 현재 path(경로)를 알 수 있다.
// page.tsx
import Navigation from "../components/navigation";
export default function Home() {
return (
<div>
<Navigation />
<h1>Hello!</h1>
</div>
);
}
hydration은 서버 측에서 렌더링된 정적인 HTML과 번들링 된 JavaScript 파일을 클라이언트에게 보내고,
클라이언트 측에서 HTML 코드와 JavaScript(React) 코드를 서로 매칭시켜 동적으로 변환하여,
상호 작용이 가능한 웹 페이지로 만드는 과정이다.
💡 정리하면, hydration 과정은
1. Next.js는 클라이언트의 요청을 응답하기 전에 서버 측에서 모든 page와 component를 렌더링하여 정적인 HTML로 만들, 이를 JavaScript 파일과 함께 클라이언트에게 준다.
2. 서버에서 프레임워크가 초기화된다. 또한 이렇게 전달받은 초기 HTML 위에 React 애플리케이션을 초기화한다.
3. 초기화 과정에서 button, link 등 정적인 HTML이 dynamic한(동적인) HTML로 변환된다.
4. 그리고 또한 eventListener들도 추가되며 웹 사이트를 보다interactive하게 만든다.
이처럼 자바스크립트 사용 중지인 상태에서 button을 클릭하면 어떠한 변화도 일어나지 않고, 서버단에서 페이지가 새로고침되어 전체 화면이 로드된다.
그러나 자바스크립트 사용 중지를 풀게되면 hydration 과정을 통해 HTML과 자바스크립트를 이용하여 button에 이벤트도 발생하고, 새로고침도 브라우저단에서 발생하여 전체 화면이 재로드되지 않는다.
또 한 번 정리하면, 서버 측에서 렌더링된 지루한(정적인) 초기 HTML이 있고,
사용자가 이 지루한(정적인) 초기 HTML을 얻고 나면,
지루하지 않은(동적인) interactive한 HTML을 만들기 위해
그 HTML 위에 React 애플리케이션과 Next.js 애플리케이션을 생성하여
dynamic한(동적인) HTML로 변환하고 event들을 추가하여 interactive하게 한다.
그리고 이를 hydration 이라고 한다.
그러나 hydration 과정이 모든 component에 대해 발생하지는 않는다.
클라이언트에서 hydrate 되는(interactive 되는) components는
오!직! 맨 위에 "use client" 지시어를 갖고 있는 component들 뿐이다.
즉, "use client"는 Backend에서 렌더링되고 Frontend에서 hydrate 및 interactive 됨을 의미한다.
그러므로 클라이언트 component를 사용하지 않는(= "use client"를 선언하지 않은) 모든 것들은 기본적으로 서버 component이다.
또한 사용자는 "use client"를 가진 components의 JavaScript 코드만 다운받게 된다.
그러므로 "use client"가 많을수록 로딩이 오래걸리므로, 필요한 경우일 때만 선언하는 것이 좋다.
[React] 리액트는 프레임워크? 라이브러리?
React 는 왜 프레임워크가 아니라 라이브러리일까?
리액트 렌더링 및 최적화
Next.js의 Hydrate란?