Next.js-x.com(트위터) 클론코딩(1)
사이드 프로젝트 하나를 거하게 말아먹고 프론트엔드 개발자이지만 서버 쪽을 공부해보기로 하며 next.js 스터디를 하게 되었다.
next.js를 이용해 x.com(트위터) 클론코딩 하는 강의를 듣기로했는데 이 강의를 듣게 된 결정적인 이유..
이 자극적인 제목들.. 하지만 격하게 동감한다..!
백엔드쪽에서 api를 너무 늦게 줘서 시간이 많이 딜레이 되었기 때문에 더 이상 이 프로젝트를 진행할 시간적 여유가 되지 않았고,
이로 인해 서버에 관심 갖게 되었음.. 나중에 안 사실이지만 무작정 서버를 기다리는 것 만큼 미련한 짓도 없다는걸 알게 되었고..
MSW를 사용해 미리 연결해볼 수도 있다는 것도 알게 되었지만...그때는 몰랐을 뿐이고🥲
https://www.inflearn.com/course/next-react-query-sns%EC%84%9C%EB%B9%84%EC%8A%A4
Next + React Query로 SNS 서비스 만들기 - 인프런 | 강의
리액트18 & 넥스트14 & 리액트쿼리5 & Next Auth5 & MSW2 & socket.io4 & zustand 스택으로 트위터(X.com)와 유사한 SNS 서비스를 만들어봅니다. 끝으로 검색엔진 최적화를 위한 SSR까지!,...
www.inflearn.com
이 글은 강의를 진행하면서 정리할 겸 타임어택 과제이기도 해서 정보를 얻기에 적합하지 않음을 미리 알려드립니당ㅎㅎ(강의 보세요!)
[공식문서]
https://nextjs.org/docs/getting-started/installation
Getting Started: Installation | Next.js
Create a new Next.js application with `create-next-app`. Set up TypeScript, styles, and configure your `next.config.js` file.
nextjs.org
next.js의 폴더 구조를 보면
public 폴더는 모든 사람들이 접근 할 수 있는 것들을 넣어줌.
ex) 이미지 파일 같은 것들
src는 진짜 코드들, app은 주소를 담당하는 router를 담음.
모든 사용자마다 폴더를 만들 수 없기 때문에 [username]이라는 폴더를 만들어서 대응한다.
[username]은 다른 폴더 이름을 제외한 나머지만 대응한다.
따라서 username은 폴더명이 되지 않도록 해야 함!
() 소괄호는 주소창에 관여하지 않음!
폴더를 만드는 이유는 layout을 만들기 위해서 임이 큰데 layout은 페이지를 이동해도
리렌더링이 되지 않고 그대로 유지한다.
만약 레이아웃이 리렌더링되게 하고 싶으면 layout.tsx가 templete.tsx로 만들어 사용하면 된다!(공존하면 안됨! )
templete.tsx을 사용하는 이유: 페이지를 넘나들때마다 기록이 필요한 경우, 구글 애널리스틱을 사용할 때도 사용.
사실 리렌더링 보다는 매번 새롭게 마운트된다고 생각하면 된다.
<Link href="/i/flow/signup" className={styles.signup}>계정 만들기</Link>
next에서는 a 태그 대신에 Link를 사용한다. a태그를 사용하면 새로 고침이 되기 때문이다.
리액트나 넥스트에서는 새로고침 되는 행동을 해서는 안됨!
global css와 module css 구분하기
특정한 css는 moodule css에 넣어놓으면 된다.
요즘 새로 나온 단위.
width: 100dvw;
height: 100dvh;
전체 화면을 채울 수 있는 방법. 100%를 사용해도 되지만 모바일 창에서 주소창이 생겼다 없어졌다 할때 사용하기 좋음!
[패러렐 라우트]
뒤에 이미지와 앞에 모달을 동시에 나오게 하기 위해서 앱라우터에서는 페러렐 라우트를 사용하면 된다!
[인터셉터 라우트]
(.)i 는 이전의 내용을 가르킴.
@modal또한 주소에 포함되지 않기 때문에 (.)i 와 i 는 같은 선상에 놓이게 된다.
<Link
href="/i/flow/login"
className={styles.login}
> 로그인 </Link>
로그인 버튼을 눌렀을 때 /i/flow/login으로 가야 하지만 인터셉팅 라우트를 사용해 주소를 가로채기 때문에 실제로 열리는 창은 /(.)i/flow/login이다! @modal 폴더 안에 있기 때문에 {children}이 아닌 {modal}이 뜬다!
// layout.tsx
import { ReactNode } from "react";
import styles from "@/app/page.module.css";
type Props = { children: ReactNode; modal: ReactNode };
export default function Layout({ children, modal }: Props) {
return (
<div className={styles.container}>
{children}
{modal}
</div>
);
}
그렇다면 /i/flow/login을 평생 사용할 일 없어보이지만 그렇지는 않음!
새로고침 했을 때 나오는 것은 /i/flow/login 이 안에 있는 page.tsx임.
정리!
링크를 눌러 로그인 창을 누르면 /(.)i/flow/login이 실행된다.
새로고침을 하거나 주소창에 입력할 경우 나오는 건 /i/flow/login이다!!!
팁!
서버컴포넌트는 클라이언트 컴포넌트를 임포트 해도 되지만 클라이언트 컴포넌트는 서버 컴포넌트를 임포트 하면 안됨!
(서버 컴포넌트가 클라이언트 컴포넌트로 바뀜)
리다이렉트의 경우 서버 컴포넌트에서 하게 되면 오류가 생기기 때문에 클라이언트 컴포넌트로 바꿔주면 된다!
// 서버 컴포넌트
import { redirect } from "next/navigation";
export default function Login() {
redirect("/i/flow/login");
}
// 클라이언트 컴포넌트
"use client";
import { useRouter } from "next/navigation";
import Main from "../_component/Main";
export default function Login() {
const router = useRouter();
router.replace("/i/flow/login");
return <Main />;
}
// router.push
// localhost:3001 => localhost:3001/login => localhost:3001/i/flow/login
// 뒤로 가기 누르면 localhost:3001/i/flow/login => localhost:3001/login =>
// localhost:3001/i/flow/login => localhost:3001/login (무한 반복)
// router.replace
// localhost:3001 => localhost:3001/login => localhost:3001/i/flow/login
// 뒤로 가기 누르면 localhost:3001/i/flow/login => localhost:3001
next는 클라이언트 컴포넌트와 서버 컴포넌트들로 나뉜다.
대부분은 서버 컴포넌트임. 따라서 async를 사용해 비동기 처리를 할 수 있음.
하지만 서버 컴포넌트로 사용하게 되면 useState, useEffect 같은 hooks를 사용할 수 없음.
hooks를 사용하기 위해서는 클라이언트 컴포넌트로 바꿔줘야 함!
맨 위에
"use client";
붙여주면 클라이언트 컴포넌트로 사용 가능하다.
사실 서버 컴포넌트의 장점은 데이터와 관련 있음. 이러면 서버 컴포넌트의 장점이 사라짐!
[프라이빗 폴더]
프라이빗 폴더: 겹치는 컴포넌트를 한번에 몰아 넣을 수 있음! 주소창에 뜨지 않음.
주소창에 뜨지 않는 폴더 3개
1. group folder -레이아웃을 두는 역할
ex) (afterLogin)
2. 패러렐 라우트 - 한 화면에 두개의 화면을 동시여주는 용도
ex) @modal
3. privite folder - 폴더 정리용
ex)_component