Today I Learned
- 스파르타 Next.js 강의 수강
- 노마드코더 Next.js 강의 수강
- Programmers 문제 풀기
스파르타 Next.js 강의 내용 정리
_app.js 와 _document.js
_app.js
- Next.js의 root component에 해당하는 파일.
- 사용 예시
- 글로벌 CSS적용
- 초기값 설정
_document.js
- HTML 구조를 커스텀할 때 사용.
- 오직 Server Side에서만 렌더링 됨
- CSS와 같은 스타일이 초기 HTML 렌더링 시에 적절하게 적용될 수 있도록 도움
- 예시) styled-components 사용 시 document.js가 없으면 초기에 깜빡거림.
- ServerStyleSheet을 사용하는 것으로, styled components로부터 만들어진 styles이 HTML 초기 렌더링에 포함되는 것을 확인할 수 있음.
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
)
}
} finally {
sheet.seal()
}
}
}
export default MyDocument
By using ServerStyleSheet, you can make sure that the styles generated by the styled components are included in the initial HTML response from the server, avoiding the FOUC and providing a better user experience.
Regenerate response
Web Vitals
- 사용자 경험은 웹 사이트의 품질을 결정하는 지표 중 하나이다. 구글은 웹사이트에 대한 사용자 경험을 측정하기 위해 Core Web Vital을 공개했다.
- LCP(Largest Contentful Paint): 페이지의 로딩 성능을 측정하는 항목.
- FID (First Input Delay): 페이지의 응답성을 측정하는 항목.
- CLS (Cumulative Layout Shift): 시각적 안정성을 측정하는 항목. Next에서 제공하는 기본 컴포넌트인 next/image 를 이용하면 개선할 수 있다.
- Chrome Lighthouse를 이용하면 대략적인 Web Vital을 측정할 수 있다.
Middleware
앱 사이에 있는 소프트웨어이다. Next.js의 경우, 특정 페이지로 이동을 해서 요청을 보냈을 때, 그 요청에 대한 응답을 받기 전 Middleware를 통해 다양한 작업을 할 수 있다.
import { NextRequest, NextResponse } from "next/server";
export default function middleware(request: NextRequest) {
const url = request.nextUrl.clone();
const { pathname } = request.nextUrl;
if (pathname === "/ping") {
url.pathname = "/pong"
return NextResponse.redirect(url);
}
if (pathname === "/ping") {
url.pathname = "/pong"
return NextResponse.rewrite(url);
}
};
- 비로그인 유저 제한
- request에 존재하는 cookie를 검사해서, 비로그인 유저를 검사한다.
- redirect
- 특정 URL을 서버에서 바로 리다이렉트 한다.
- rewrite
- 특정 URL을 보여주면서, 다른 페이지를 보여주고 싶을 때 사용한다.
Next.js에 Typescript 적용하기
import { GetStaticProps, GetStaticPaths, GetServerSideProps } from 'next';
export const getStaticProps: GetStaticProps = async (context) => {
// ...
};
export const getStaticPaths: GetStaticPaths = async () => {
// ...
};
export const getServerSideProps: GetServerSideProps = async (context) => {
// ...
};
출처 https://nextjs.org/learn/excel/typescript/nextjs-types
노마드코더 Next.js 강의 내용 정리
라이브러리 vs 프레임워크
라이브러리와 프레임워크의 주요 차이점은 "Inversion of Control"(통제의 역전)이다. 라이브러리에서 메서드를 호출하면 사용자가 제어할 수 있지만, 프레임워크에서는 제어가 역전되어 프레임워크가 사용자를 호출한다.
- 라이브러리: 사용자가 파일 이름이나 구조 등을 정하고, 모든 결정을 내림
- 프레임워크: 파일 이름이나 구조 등을 정해진 규칙에 따라 만들고 따름
Pages
pages 폴더 안에 있는 파일명에 따라 route가 결정된다.
파일 안에 컴포넌트명은 상관없지만 반드시 export default를 해줘야 한다.
pages/about.js 생성 -> localhost:3000/about (O)
다만 예외사항으로, index.js의 경우에는 앱이 시작하는 파일이라고 보면 된다.
즉 localhost:3000 그 자체다. 뒤에 /index로 붙이면 안 된다.
CSS Modules
// components/NavBar.js
import Link from "next/link";
import { useRouter } from "next/router";
import styles from "./NavBar.module.css";
export default function NavBar() {
const router = useRouter();
return (
<nav>
<Link href="/">
<a
className={`${styles.link} ${
router.pathname === "/" ? styles.active : ""
}`}
>
Home
</a>
</Link>
<Link href="/about">
<a
className={[
styles.link,
router.pathname === "/about" ? styles.active : "",
].join(" ")}
>
About
</a>
</Link>
</nav>
);
}
// components/NavBar.module.css
.link {
text-decoration: none;
}
.active {
color: tomato;
}
Styles JSX
import Link from "next/link";
import { useRouter } from "next/router";
export default function NavBar() {
const router = useRouter();
return (
<nav>
<Link href="/">
<a className={router.pathname === "/" ? "active" : ""}>Home</a>
</Link>
<Link href="/about">
<a className={router.pathname === "/about" ? "active" : ""}>About</a>
</Link>
<style jsx>{`
nav {
background-color: tomato;
}
a {
text-decoration: none;
}
.active {
color: yellow;
}
`}</style>
</nav>
);
}
_app.js
import NavBar from "../components/NavBar";
import "../styles/globals.css";
export default function MyApp({ Component, pageProps }) {
return (
<>
<NavBar />
<Component {...pageProps} />
</>
);
}
Programmers 문제 풀기
약수의 합
나의 풀이
function solution(n) {
let answer = 0;
for ( i = 1; i <= n; i++) {
if ( n % i === 0 ) {
answer += i;
}
}
return answer
}
자릿수 더하기
나의 풀이
function solution(n) {
return n.toString().split("").reduce((acc, cur) => acc + parseInt(cur), 0)
}
자연수 뒤집어 배열로 만들기
나의 풀이
function solution(n) {
let array = n.toString().split("");
let answer = [];
for ( i = array.length - 1; i >=0; i--) {
answer.push(+array[i])
}
return answer;
}
풀이 수정
function solution(n) {
return n.toString().split("").reverse().map((num) => +num);
}
for문으로 풀고 나서 갑자기 배열을 뒤집어주는 메서드를 검색해 봤는데 reverse()라는 게 있길래 풀이를 수정해 봤다. 근데 reverse만으로는 문자열을 숫자로 만들 수 없어서 map을 한 번 더 돌려줬다.
회고
오후에 잠시 리더/부리더 세션이 있어서 같이 신청한 분과 프로젝트 컨셉에 대해 많은 얘기를 나눴다. 그 외에는 프로그래머스 문제도 좀 풀고, 노마드코더에서 무료로 제공하는 next.js 강의를 들었다. 처음에는 꼭 next.js를 최종프로젝트에 써야 될까? 어려워 보이는데 next.js 포기하고 타입스크립트라든지 다른 부분에 더 집중하는 게 좋지 않을까? 라는 생각을 했었는데 배우면 배울수록 좋은 점이 많아서 최종프로젝트에 적용해보고 싶은 욕심이 난다. 그래서 주말 동안 강의도 듣고 next.js를 열심히 공부할 계획이다.