1. Next.js 프로젝트 셋업
npx create-next-app@latest --experimental-app
- 전부 NO로 선택함
- Next 버전을 13.2.4로 진행
- 그리고
npm install
해주고 npm run dev
하면 웹페이지가 열림
2. 폴더 및 파일설명
- 메인페이지는 app폴더안에 page.js가 될거고 그걸 감싸고있는 head 상단바 등은 layout.js파일이 될거임
- globals.css는 모든페이지에 적용될 css파일이고, nodule.css는 특정페이지에만 적용할 css임
- public 폴더는 이미지나 폰트들을 저장할 폴더임
3.Next시작
ㄱ. 시작
- page안에 내용들 지우고 globals.css내용들도 지우고 시작
ㄴ. 페이지라우팅하기
- list라는 폴더를 app폴더안에 만듬 그럼
http://localhost:3000/list
라고 라우팅 페이지를 만들수 있음 폴더명이 /뒤에 붙는 이름이라고 생각하면됨
- 그리고 파일명은항상 page.js 혹은 tsx(타입스크립트)함
ㄷ. 페이지로 이동
- 이제 nav바안에 링크버튼을 만들어서 눌러서 이동하는걸 만드려고함 그럴때 사용하는게
<Link>
태그임 a
태그와 같은 방식으로 작동함 <Link href="/">home</Link>,<Link href="/list">list페이지</Link>
/태그는 home이고 /list는 list페이지로 이동임
ㄹ. 레이아웃.js
- 만든 Nav를 모든 페이지에서 보여주고싶으면 layout.js파일안에 넣으면 모든페이지를 가도 보여주게됨
{children}
이라고 되어있는건 메인페이지의 page.js의 부분임!
- 그런데도 메인뿐만아니라 list페이지에서도 레이아웃이 보이는 이유는 Next의 동작원리때문인데 어떤폴더의 상위폴더에 layout.js가 있으면 layout이 적용이됨 즉 layout.js밑에있는 폴더들을 다 layout.js가 적용되서 보여줌
ㅁ. 최적화된 이미지 넣기
- 최적화된 이미지를 넣어야하는이유는 layout Shift를 방지하기때문임 layout Shift란 이미지가 html글 보다 늦게 렌더링이되는거라고 보면됨(레이아웃이 밀림)
- Next에서 사용하려면 Image를 import 하고 쓰면 됨
- 근데 이렇게하려면 Image src안에 경로를 적으면 안되고 사진까지 import해와서 적용해줘야함
- 외부에있는 이미지를 넣을때는 width와 height 속성을 꼭 써줘야함
- 그리고 next.config.js 파일에도 어느사이트에서 가져왔는지 적어줘야하는 불편함이 있음
ㅂ. 컴포넌트(서버, 클라이언트)
- Next는 기본 컴포넌트는 서버컴포넌트임
- 클라이언트 컴포넌트를 사용하고싶으면 파일 맨위에
"use client"
라고 적으면 그파일은 클라이언트 컴포넌트가 됨
- 둘의 차이점은 서버클라이언트에서는 자바스크립트 기능을 못씀 예를들어서
<div onClick={}>
이런거 안됨 물론 리엑트랑 사용한다면 useState나 useEffect도 안됨
ㅅ. import export 문법
- 별도의 파일에 있는 변수나 함수를 export로 내보내고 import로 다른파일에서 불러올수 있음
let age = 20; export default age;
으로 내보내고 다른파일에서 import 작명 from 경로
적으면 "작명"이라는 이름으로 사용이 가능함
- 만약 변수혹은 함수가 여러개면
export{age, name}
이런식
2.게시판 만들기
ㄱ. 몽고디비 연결
ㄴ. dynamic route로 상세페이지
- detail 폴더를 만들고 그안에
[폴더명]
쓰고 page.js 만들면
- 웹페이지상에서 detail/아무거나 입력해도 해당페이지로 이동하게됨
- props를 인자로 받아서 출력하면 /detail/""이안에 입력된값을 props로 받아와서 터미널에 출력해주고있음
- 그래서 detail/뒤에 게시물의 id값을 넣으면 상세페이지를 보여주게하려면
- post 제목클릭시 해당 post의 상세페이지로 이동하게하기
ㄷ. useRouter
<Link>
태그말고useRouter()
로 이동하려면 import { useRouter } from "next/navigation";
해야하고 클라이언트서버에서만 가능해서 "use client"
해줘야함
useRouter
를 쓰는이유는 기능때문인데 이동하기는 push, 뒤로가기는 back, 앞으로가기는 forward, 새로고침은 refresh가 있음
- 새로고침의 경우 전체 재렌더링이 아닌 업데이트된부분만 새로고침하는 soft refresh기능임
- prefetch("/페이지경로")는 페이지를 미리 로드를 해줘서 빠르게 이동할 수 있게함
- Link태그 자체에 prefetch 기능이 담겨있어서 Link태그를 너무 많이 담아두면 화면렌더링이 오래걸릴수 있는데 그랠때는
<Link prefetch={false}>
하면 기능을 끌 수 있음.
ㄹ. 글작성 하기
- 서버에 통신하려면 GET, POST, PATCH, DELETE, 등 여러가지 메소드가 있고 그걸 사용하면됨
- GET 요청하려면 app과 동일한 구간에 pages폴더안에 api 폴더안에 js파일 만들어두고 실행할 함수 넣어두고 주소창에 /api(폴더명)/test(파일명)넣으면 get 요청된거임
- 서버기능 처리성공시에는 status(200), 실패시엔(500), 유저잘못으로 실패시(400)을 쓰는 룰같은게 있음(status code라고함)
- POST 요청하기 write 폴더안에 js파일만들고 그안에서 작성해줌
- POST 일때와 GET일때 의 각각 다른내용을 보여주려면 이렇게
- 이제 input창을 만들고 그안에 입력된 데이터를 서버에서 불러온다음에 서버에 불러온걸 DB에 저장을 할거임
insertOne()
을 사용해서 몽고DB에 저장해줌
- 저장도 잘되고 작성도 잘 되었으면 해당글의 상세페이지나 리스트 페이지로 이동하는게 UX적으로 좋은데 그럴때 사용하는게
redirect()
임
ㅁ. 글 수정하기
- edit 폴더안에 [id]로 다이나믹 라우트 폴더만들고 그안에 js파일 만듬
- 그리고 수정하기 버튼을 클릭시 해당주소로이동하게함
/edit/해당글의 id
- 그리고 해당 주소의 id에 맞는 제목과 글을 불러옴
- document 수정은
updateOne()
을 사용함
- 글 등록과 마찬가지로 db에서 바로 수정하는거보다 서버를 거쳤다가 수정을해야하는게 안전함
- api폴더안에 post폴더안에 edit.js파일을 만들고 그안에서 수정이 이뤄질수 있게 해줌
ㅂ. 삭제하기
- 몽고DB에서 데이터를 삭제하려면
deleteOne()
이걸 사용해야함
- 수정과 마찬가지로 api폴더안에 post폴더안에 delte.js파일을 하나 만들고 서버에 통신하고 db를삭제하려고함
3. 회원가입 & 로그인
ㄱ. 깃헙 소셜로그인(JWT방식)
- 깃헙링크로 접속하고 Settings >> Developer settings >> new OAuth application 따라 들어가주고 이름이랑 사용할 URL 넣어줌
- Next-auth 라이브러리를 설치해줌
npm install next-auth@4.21.1
이건 JWT라는 방식의 로그인방법임
- pages폴더안에 api폴더안에 auth라는 폴더만들어주고 그안에 [...nextauth].js라는 폴더만들어줌
import NextAuth from "next-auth"; import GithubProvider from "next-auth/providers/github"; export const authOptions = { providers: [ GithubProvider({ clientId: 'Github에서 발급받은ID', clientSecret: 'Github에서 발급받은Secret', }), ], secret : 'jwt생성시쓰는암호' }; export default NextAuth(authOptions);
을 붙여넣음
- 레이아웃에 로그인 버튼을 만들건데 클라이언트 컴포넌트로 하나만들어주고
signIn()
이라는 메소드를 사용할거임
- 로그아웃할때는 signOut()을 사용하면됨 import도 해주고
- 이제 레이아웃에 있는 로그인 버튼을 누르면 이런게 보이면 성공
- 로그인된걸 확인하려면
let session = await getServerSession(authOptions); console.log(session);
하면됨 authOptions
이거는 처음 만든 [...nextath.js]파일안에 있음
- 로그아웃페이지를 하나더 만들어서 삼항연산자로 다른 컴포넌트가 보이게 설정해줌 컴포넌트를 하나더 만든이유는 클라이언트 서버에서는
authOptions
이걸 import해올수가 없음
ㄴ. 깃헙 소셜로그인 (DB adapter 방식)
npm install @next-auth/mongodb-adapter
설치해줌 이건 몽고디비 어댑터라서 다른db사용하려면 다른거 찾아서해야함
- 만약 몽고디비 사용중인데 에러가 나면
npm uninstall mongodb
이거랑 npm install mongodb@4
이거 두개하면됨
- 그다음 아까 만들어둔
[...nextauth].js
파일안에 adapter: MongoDBAdapter(connectDB)
이 부분을 추가해줌
- 그다음에 페이지에서 다시 로그인을 하면 이번엔 몽고디비 사이트에 test라는 컬렉션이 추가가되어있음
- sessions은 현재 로그인된 유저의 세션정보 저장용임
- users는 현재가입된 유저의 정보가 담겨있음
- accounts은 가입된 유저의 계정정보(깃헙 등)가 담겨있음
- 만약 test라는 컬렉션말고 fourm에 컬렉션을 만들고싶으면 만들어둔 database.js파일에 uri를 수정해줘야함
- 이제 post 수정,삭제를 해당글을 작성한 사람만 작동하게 해야함 그러러면 글등록할때 유저의 이메일도 같이 전송해줘야함
- 이제 저기 이메일과 로그인된 이메일이 같으면 수정이랑 삭제가 되게 해줘야함
- 상세페이지에서 포스트 작성한 이메일과 로그인된 유저의 이메일이 같은경우에만 수정버튼과 삭제버튼이 보이게 해줌
ㄷ. 다이나믹 렌더링 스태틱 렌더링
npm run build
를 하면 페이지가 어떤방식으로 작동하는지 알 수 있음.
- λ은 다이나믹 렌더링으로 유저가 페이지에 접속할때마다 새로 html을 만들어서 보여줌
- ○은 스태틱 렌더링으로 항상같은 html을 보여주게됨
- 만약 스태틱 렌더링을 하는 페이지를 다이나믹 렌더링 페이지로 변경해주려면 해당 페이지의 파일에
export const dynamic="force-dynamic
해주면 다이나믹렌더링으로 바뀜
- 반대의 경우라면
export const dynamic="force-static
으로 해주면됨
- 그런데 다이나믹 렌더링은 유저가 볼때마다 렌더링을 새로해주기때문에 서버나 db에 부담이 있을수 있는데 이걸 방지하기 위해서 캐싱을 사용하면 부담을 줄일수가 있음
- 캐싱하고싶은 페이지의 상단에 사용가능