Next.js 기초

이윤희·2025년 2월 11일

React/Next 일기

목록 보기
40/52

혼자 공부/복습한 것 정리했는데
코딩애플님 강의 듣고 있어서 layout 설명 같은건 강의에 있던 그림을 첨부했다. 참고.

설치

npx create-next-app@14

App router 는 yes 로 함
난 tailwind CSS 도 써볼거라서 같이 깔았다.

실행 명령어는 npm run dev

app 폴더 : 내가 코드짤 폴더

page.js : 메인페이지

layout.js : 메인페이지 감싸는 용도 (헤더같은 공통 요소들)

public 폴더 : 이미지나 static 파일 보관용

api 폴더 : 서버기능 만드는 곳

next.config.js : nextjs 설정 파일

node_modules 폴더 : 설치한 라이브러리 보관용 폴더

package.json : 설치한 라이브러리 버전 기록용 파일


Routing

Next.js에서는 따로 라우팅 할 필요 없고,
폴더와 파일 하나만 만들면 자동으로 라우팅이 된다고 함!!!

  1. app 폴더 아래에 폴더 하나 만들고(여기서 작명한 게 URL이 됨)
  2. 그 폴더 안에 page.js 파일을 만든다.

그러면 라우팅 끝!!!

폴더 안 page.js에 원하는 컴포넌트 집어넣어 두면 되는것


layout.js

Next에서는
page.js를 보여줄 때 layout.js 파일이 있으면
layout.js 내용 안에다가 page.js를 담아서 보여준다

{children} 이라고 표기된 부분에 page.js 가 들어감

만약에 layout.js 가 여러개 있으면 그 부모의 부모.... 들까지 전부 다 감싸서 보여줌.


숙제해봄

라우팅


ㅋㅋㅋㅋㅋㅋ 처참한 UI;; 근데 어제 본 거 중에 생각나는것들을 다 써보고 싶었음

/cart/layout.js

export default function CartLayout({ children }) {
  return (
   <div>
    <div className="bg-red-300 p-10 text-cyan-600 rounded-full border-x-5 ring-4 mb-11">
        현대카드 할인 이벤트 중입니다.
    </div>
        {children}
   </div>
  );
}

map 사용

let 상품 = ['Tomatoes', 'Onion', "Potatoes"]
return (
  <div  className="bg-slate-700 p-10">
    <h1 className="font-extrabold">리스트 페이지입니다.</h1>
    <h2>상품 목록 </h2>
    <div className="food">
      <h4>{상품[0]}  $40</h4>
    </div>
    <div className="food">
      <h4>{상품[1]}  $40</h4>
    </div>
    <div className="food">
      <h4>{상품[2]}  $40</h4>
    </div>
  </div>
);

이거를 다시 map으로

근데 여기서 주의할 점!!!!!!!!!

return ( ) 을 해줘야 html이 나옴.

상품.map((_, i)=>{
  <div className="food">
    <h4>{상품[i]}  $40</h4>
  </div>
})

그냥이렇게 쓴다고 오류는 안나지만 얘가 안뱉어줘서 HTML 이 그자리에 안남음 -> UI가 안뜸

상품.map((_, i)=>{
  return (
    <div className="food">
      <h4>{상품[i]}  $40</h4>
    </div>)
})

이렇게써줘야 [ <div>, <div>, <div> ] 이렇게 반환이 돼서 HTML이 보임

ㅡㅡ 이실수 계속함

<h4 className="title">Cart</h4>
{
  myCart.map((_,i)=>{
    <CartItem item={myCart[i]}/>
  })
}
</div>

return 하는거 잊지 말것!!!!!!!


public 폴더에 있는 이미지는 /부터 시작해도 된다.

굳이 해당 폴더에서 시작해서 ./../../../public 이렇게 안 해도 됨,,,
(또 하지 말라고 적어둠)


이미지넣기

여태 자꾸 이미지가 안나오길래 뭐지했는데 ㅠ

<img src={"/food"+i+".png"}></img>

여기서 뒤에 확장자 붙이는걸 깜빡해서 그런거였음;;

Image 컴포넌트

Image 태그를 쓰면 자동으로 이미지 lazy loading & 사이즈 최적화 & layout shift 방지를 해준다고 함

근데 좀 귀찮긴한듯
1. Image import 해오고
2. 이미지 경로도 src에 쓰면 안되고 import 해서 써야 하고

만약에 다른사이트에서 가져온다면

  1. width, height도 지정해줘야 되고 (왜지? 근데 진짜 안했더니 오류난다)
    (아니면 fill="true" 넣고 부모 div에 width, height 조정해도 된다고함)
  2. 이렇게 세팅도 따로 해줘야 함;;

보통은 그냥 img 쓸거같긴 한데 ?? 실제로 어떨지는 모르겠네
엄청 큰 이미지라면 쓸만할지도 모르겠다



use client


컴포넌트 좀 재렌더링하면서 확인하려고 버릇처럼 useState 썼는데 이런 에러가 떠서 확인해보니
생각해보니까 서버 컴포넌트에서는 useState useEffect ... 이런거 사용이 안된다고 했었다.

'use client'
import { useState } from "react";

이렇게 하니까 잘됨


props


리스트 좋아요버튼

{
  상품.map((_, i)=>{
    return (
      <div className="food" key={i}>
        <img src={"/food"+i+".png"}></img>
        <h4>{상품[i]}  $40</h4>
        <span> {cnt[i]} </span>
        {/* 얘를 클릭하면 해당 아이디 번째의 cnt 를 1 증가시킨다. */}
        <button className="bg-black p-2 rounded-full text-white font-bold " onClick={()=>{
            let copy = [...cnt];
            copy[i] = copy[i] + 1;
            setCnt(copy);
          }}> + </button>
      </div>)
  })
}

오늘의 숙제 :

버튼누르면 상품수량이 +1/-1 되는 기능을 완성해옵시다.

+는 만들었는데
-하려고하니까 안된다.
왜 이게 무조건 false 가 되지??

{/* 얘를 클릭하면 해당 아이디 번째의 cnt 를 1 증가시킨다. */}
<button className="bg-black p-2 rounded-full text-white font-bold " onClick={()=>{
    let copy = [...cnt];
    copy[i] = copy[i] + 1;
    setCnt(copy);
  }}> + </button>
<button className="bg-black p-2 ml-3 rounded-full text-white font-bold " onClick={()=>{
    if(cnt > 0 ){
      let copy = [...cnt];
      copy[i] = copy[i] - 1;
      setCnt(copy);
    } else { 
      alert('1 이상의 수량만 가능합니다.');
    }
  }}> - </button>

계속 else만 뜬다

=> 아 ㅡㅡ
조건을 잘못줌
cnt > 0? 이 아니고
cnt[i] > 0? 이었어야 함!!!!!

{/* 얘를 클릭하면 해당 아이디 번째의 cnt 를 1 증가시킨다. */}
<button className="bg-black p-2 rounded-full text-white font-bold " onClick={()=>{
    let copy = [...cnt];
    copy[i] = copy[i] + 1;
    setCnt(copy);
  }}> + </button>
<button className="bg-black p-2 ml-3 rounded-full text-white font-bold " onClick={()=>{
    if(cnt[i] > 1 ){
      let copy = [...cnt];
      copy[i] = copy[i] - 1;
      setCnt(copy);
    } else { 
      alert('1 이상의 수량만 가능합니다.');
    }
  }}> - </button>

장바구니니까 1보다큰걸로 줬고
이걸로 기초강의들 숙제 끝~~

0개의 댓글