개인공부/next

Next.js 공부 (1)

minseokiim 2023. 12. 14. 04:59

* 폴더구조
- public : 넥스트 서버에서 누구나 접근할 수 있게 서빙해줌
-  src : 이 안에 app폴더 둘 수 있음, 이렇게 하면 장점=> app폴더에는 주소와 관련된 파일들만 들어가므로, 주소와 관련 없는 파일들은 app폴더 바깥에다 두면 됨, 같은 맥락으로 mock폴더 등등 둘 수 있음
=> src안에는 진짜 코드들이 들어있고, src의 일부(ex. app)는 라우팅 담당, 주소가 twitter.com/i/flow/signup -> i폴더안에 flow폴더안에 signup 폴더 이런식으로 생성
-  next.config.js : 유일한 js 파일, 넥스트에 대한 설정

 

* layout

layout에 있는 children에 page가 들어가는 것

/app/layout.tsx : 모든 페이지의 공통 레이아웃, 만약 Home만의 레이아웃을 만들고 싶다면 그 디엑토리에 만들어주기

그러면 root layout의 children에 home의 layout이 들어가는 구조

 

* slug?

회원마다 회원 아이디/status/게시글 아이디 주소가 존재하는데 이걸 매번 만들 수 없음 -> 넥스트에서는 slug제공(* slug: 데이터에 따라 동적으로 페이지를 만들 수 있는 기능)
ex) elonmusk/status/164565  -----> [username]/status/[id]

 

+ 만약 username 이 home이라면, home디렉토리와 폴더 겹치는거 아닌가?

이런경우, [username] 최후순위임 같은 깊이의 디렉토리(home, i, compose...)중 걔네들이 아닌 나머지가 [username]에 들어간다고 보면 됨

 

 

* 주소창에 관여하지 않는 그룹 , ()

로그인 전 후의 레이아웃이 다르다면 ? 앱 라우터에서는 이 점을 쉽게 해결
/app/밑에 (beforeLogin), (afterLogin) 폴더를 만들어줌, 소괄호의 역할 : 주소창에 관여를 하지 않지만 그룹을 만들 수 있음

 

 

* layout.tsx과 template.tsx의 차이?

- layout.tsx : 페이지 넘어갈때 레이아웃 리렌더링 안되게
- template.tsx : 페이지 넘어갈때 레이아웃 리렌더링 되게=페이지 넘어갈때마다 매번 새롭게 마운트 되게

ex. 페이지 넘어갈때 레이아웃은 리렌더링 안되고 페이지만 리렌더링 되는데, 만약 레이아웃도 리렌더링 되었으면 한다면, 페이지 넘어갈때 기록남겨야한다면, 구글 애널리틱스 ..  -> template.tsx 사용하기


-> 둘의 공존은 불가, 하나를 선택하기

 

 

* Link, Image 태그

1) Next에서는 a태그 대신 Link를 씀
a태그를 쓰면 페이지가 새로고침 되며 넘어가는데 리액트/넥스트에서는 새로고침 되면 안되므로.

 

2) Next에서는 Image태그를 씀, 자동으로 이미지 최적화 해주는 장점이 있음

 

 

* 페러렐 라우트

 두가지 화면을 한페이지에서 동시에 보여줌, 같은 폴더가 아니면 패러렐이 될 수 없음, 레이아웃에서 사용

ex. @modal 하면, <div>{children} {modal}</div>=> 그냥 페이지는 children에, 페러렐라우트는 modal로 감

 

-> 모달을 띄우는 것은 패러렐 라우트로 구현, 하지만 모달 띄우면 뒤의 배경이 사라지는 문제 발생!

 

* 인터셉팅 라우트
: 서로 주소가 다른데 같이 뜰 수 있게 해주는 것

/(beforeLogin)/@modal/i 가  /(beforeLogin)/i를 대체 하게 하기

@modal에 (.i)폴더 생성하면 (beforeLogin)이 아니라, (beforeLogin)의 부모인 app으로 감
이유 : @modal도 주소에 해당하는 애가 아니기 때문에 무시됨, .은 현재 폴더 경로를 의미하므로, (.i)로 만들어주어야함

 

 

* 서버 컴포넌트

서버 컴포넌트는 넥스트 js 서버에서 돔, 리액트 18에서 추가된 개념
리액트는 클라이언트에서 돌아야함
서버에서 돌기 때문에 layout.tsx에 export default async function Layout 이런식으로 async 할 수 있음

 

-> 단점 : useState, useEffect 같은 hooks들을 못씀

 

* 클라이언트 컴포넌트
훅들(use Router, useSelectedLayoutSegment, useState..), 이벤트 리스너들(onClick ..)을 쓰기 위해서는 클라이언트 컴포넌트로 바꿔줘야 함 => "use client";를 상단에 써주기

 

"use client"를 쓰면 서버 컴포넌트 쓰는 장점이 없으므로 모든 페이지에서 쓰지 않는 것임
서버 컴포넌트는 모두 데이터와 관련이 있음

 

※ 서버 컴포넌트는 클라이언트 컴포넌트를 import 해도 되는데, 클라이언트 컴포넌트는 서버 컴포넌트를 import 할 수 없음.

 

 

* redirect, router

서버에서 리다이렉트 하면 인터셉팅이 잘 되지 않음, 링크 통한 클라이언트 리다이렉팅으로 바꿔주기

 

기존) redirect("/i/flow/login"); -> 

변경) "use client"; 

import { useRouter } from "next/navigation";

const router = useRouter();
router.replace("/i/flow/login"); 

 

* router.push와 router.replace의 차이?

1) router.push의 경우
localhost:3001 -> localhost:3001/login -> localhost:3001/i/flow/login
localhost:3001/i/flow/login 에서 뒤로가기 하면 localhost:3001/login
(결국 localhost:3001/login에서 또 localhost:3001/i/flow/login를 실행하는 문제, 빠져나올 수 없음)


2) router.replace의 경우
localhost:3001 -> localhost:3001/login -> localhost:3001/i/flow/login
localhost:3001/i/flow/login 에서 뒤로가기 하면 localhost:3001(로그인보다 더 이전으로 감)

 

 

* private폴더, _

앞에 _를 붙이면 private폴더가 됨, 주소창에 안뜸

ex. _components 폴더

 

 

* useSelectedLayoutSegment, active link

주소랑 연동이 됨
client component로 만들어야 함(훅이므로)

 

-> const segment = useSelectedLayoutSegment();
 console.log(segment);
  //   홈에 있으면 segment가 홈이 됨, 현제 레이아웃에 있는 폴더들이 나옴

 

 

* useSelectedLayoutSegment, useSelectedLayoutSegments 차이?

const segment = useSelectedLayoutSegment();
console.log(segment); // compose

 

const segment = useSelectedLayoutSegments();
console.log(segment); // ['compose','tweet']