# nextjs 13버전
- 폴더기반 자동라우팅
- 새로디자인한 서버API 기능
- 쉬운 DB연결
- 직관적인 rendering 전략 선택기능
- hydration없는 server-side rendering
- 파워풀한 캐싱
- 이미지와 폰트 최적화
# 개발 환경 셋팅
- nodejs 설치(lts버전 - node 18버전이상)
- vscode 에디터 설치
- nextjs 설치 (npx create-next-app@latest)
# 폴더 설명
- app 폴더 : 코드짤 폴더
- page.js : 메인페이지 (typescript를 쓰고 싶다면 tsx로 확장자를 바꾸면 된다.)
- layout.js : 메인페이지 감싸는 용도의 페이지
- public 폴더 : 이미지나 static 파일 보관용
- api 폴더 : 서버기능 만드는 곳
- next.config.js : nextjs 설정 파일
- node_modules 폴더 : 설치한 라이브러리 보관용 폴더
- package.json : 설치한 라이브러리 버전 기록용 파일
# 더알아가기 문법
- XXX.module.css 특정페이지에서만 적용가능
- style 넣고 싶으면 object 자료형으로 style={ } 안에 넣어야함 style={{ color: 'red'}}
- scss로 쓰고 싶다면 확장자 변경 및 설치 npm i sass
- 라이브러리 설치 후 노드 재시작
- 페이지 나누는걸(url로 페이지를 나누는 것) 전문용어로 라우팅이라함(rest api 작명법을 참고하여 url 작명) - app 폴더 아래 폴더명이 자동으로 url 명이 됨(page.tsx가 메인페이지이다)
- 레이아웃의 경우 중첩 레이아웃 원리로 이루어져 있다. 상위의 모든 레이아웃을 합치고 마지막 옆의 레이아웃도 합치게 된다. ({children} 부분이 page.tsx가 담기는 부분)
- jsx의 데이터바인딩 문법 : html안에 중괄호 안에 변수 넣기
# export
// export 할곳
let age = 20;
let name = "sunny";
// export default age; // 한개밖에 못씀
export {age, name} // 여러개를 뺄때 이렇게
# import
import {age, name} from '@/app/cart/data';
// data.js 에서 export할때 {}안에 썻으므로 import시에도 {} 써줘야함
# props
- props는 부모가 자식에게만 data를 줄수있음, 위나 옆으로 못줌;
- product={product} 처럼 작명과 데이터명을 같게 많이 씀
- 데이터명이 문자일경우 banner='텍스트' 처럼 데이터값을 {}안이 아니라 '' 안에 담아두 됨
export default function Cart() {
let product = ['토마도', '파스타'];
return (
<div>
<CartItem product={product} test={20}/>
</div>
)
}
function CartItem(props: {product: string[], test: number}) {
// props로 넘겨줄 값을 {} 안에 작명: type을 적어준다. - 타입스크립트 사용시
//부모 cart 컴포넌트에 product변수를 CartItem에서 쓸 수 없으므로 props로 내려준다.
return(
<>
{props.test} {props.product}
</>
)
}
# 컴포넌트 만들기
- 재사용이 많은것만 만들기, 코드를 간결하고 재사용에 용이, 페이지 규모가 엄청 클때
- 보통 폴더명으로 작명함
1. 서버 컴포넌트
- 그냥 마구 만든 컴포넌트
- html에 자바스크립트 기능넣기 불가능 (onClick 등)
- useState, useEffect 등 리액트 훅 사용불가
- 로딩 속도가 빠름
- 검색엔진 노출에 유리
2. 클라이언트 컴포넌트
- 파일 상단에 'use client' 하고 준것은 클라이언트 컴포넌트
- html에 자바스크립트 기능넣기 가능 (onClick 등)
- useState, useEffect 등 리액트 훅 사용
- 자바스크립트가 많이 필요한 만큼 로딩 속도가 느림
- hydration(하이드레이션) 필요 : html을 유저에게 보낸후에 자바스크립트로 html을 다시 읽고 분석하는일
3. 추천♦️
- 큰페이지는 서버 컴포넌트로 제작
- js 기능이 필요한 곳만 클라이언트 컴포넌트로 제작
- 성능이 중요치 않다면 클라이언트 컴포넌트로 쓰면 된다.
4. nextjs 장점
- 같은데이터요청이 여러개 오면 1개로 압축해 줌(decuplication : 디 듀플리케이션)
# useState
- const [num, setNum] = useState(0); // num = 변수, setNum은 변경함수
- 클라이언트 컴포넌트에서만 사용가능,
- state가 변경이 되면 state를 쓰는 html부분도 자동으로 변경됨(자동 재 랜더링)
- 리스트 항목처럼 한개만 쓰면 동시에 3개가 바뀌므로 array로 만든다.
1. state가 배열이나 객체가 아닐 때
'use client' // 리액트 훅 및 자바스크립트 onclick사용을 위해 적어주어야함
import React,{useState} from 'react' //useState 사용을 위해 라이브러리 import
// 컴포넌트
const [num, setNum] = useState(0);
// return문 안 소스 부분
<button onClick={()=>{
if (num < 1) return;
setNum(num - 1);
}}> - </button>
<span> {num} </span>
<button onClick={()=>{setNum(num + 1)}}> + </button>
// setNum은 변경함수라서 () 를 붙여줘야함, () 안에있는것으로 num을(기존 state) 바꿔준다.
// onClick 사용을 위해서 'use client' 작성, 클라이언트쪽이므로 터미널이 아닌 개발자 도구 콘솔창에서 확인 = 자바스크립트 기능넣으려면 client component
2. state가 배열이나 객체 일때
// 컴포넌트안
const [num, setNum] = useState<number[]>([0,0,0]);
// 소스
<button onClick={()=>{
let copy = [...num];
if (copy[index] < 1) return; // 0보다 작으면 안됨
copy[index]--
setNum(copy)
}}> + </button>
<span> {num[index]} </span>
<button onClick={()=>{
let copy = [...num]; // 복사해서 계산해야한다.
// 그냥 copy = num을 쓰면 num의 영향을 받아서 바뀐값으로 바뀌지 않게 된다(바뀌지않으면 state는 변경되지 않으므로). 따라서 [...num]으로 복사하여 num이 아닌 copy자체의 값을 인식하게 해야한다.
copy[index]++
setNum(copy)
}}> + </button>
🙄배열이나 객체에서 복사하여 쓰는 이유♦️
- state가 array일 때 변경함수로 바꾸어도 아무일도 일어나지 않기 때문
- 배열과 객체가 래퍼런스 타입이기 때문
😊javascript reference data type
- 참조형(값 그 자체가 아니라 주소를 가지게 되는것= 예 : 배열, 열거, 클래스, 인터페이스 등 - 객체나 배열등)
- 레퍼런스 타입은 레퍼런스 값을 통해 데이터를 다룬다는 점이다.
- 프리미티브 타입의 변수에 값을 대입 하면 실제로 그 값이 변수에 저장되지만, 레퍼런스 타입 변수에 객체를 대입하면 객체가 변수에 저장 되는 것이 아니라 메모리상에 객체가 있는 위치를 가리키는 정보만 변수에 저장된다. 그래서 레퍼런스 변수를 다른 레퍼런스 변수에 대입하면 객체가 복사되는 것이 아니라 참조값만 복사된다.
# 스프레드 문법 : spread operator
- 배열이나 객체 왼쪽에 붙이는 점3개
- 첫번째 용도 괄호제거용 연산자
예)
...[1,2,3] 을쓰면 1,2,3만 남음
- 두번째 용도는 배열이나 객체 복사
예)
let data1 = [1,2,3];
let data2 = [...data1];
console.log(data1 == data2) //false : 독립적인 array 복사본을 생성하므로 새로운 array로 인식
data2와 같은 독립적인 사본을 shallow copy 또는 deep copy 라고 한다.
# 리액트에서 array/object로 되어있는 state를 수정하고 싶으면 독립적인 카피본을 만들어서 수정해야 한다.
[...기존state]
{...기존state}
# next에서 iamge
- img태그를 직접 사용해도 무관하다 최적화된 이미지 사용시에 사용하는 태그이다.
- 상단에 이미지를 import하여 사용해야한다..(import 안 했는대 제대로 뜨는건 배포환경이 아니여서 그런것인가..?)
- import 하기를 원치 않다면 src 자리에 require로 감싸서 불러줘야 한다.
https://velog.io/@sms8377/Javascript-require-%EA%B0%84%EB%8B%A8-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EB%B0%8F-module.export-%EC%99%80-export%EC%9D%98-%EC%B0%A8%EC%9D%B4
- width, height 셋팅
<Image
src={`/img/food${index}.png`}
alt={item}
width={400}
height={400}
/>
- aws에 외부에 이미지가 있는 경우에는 별도의 세팅이 필요하다.
https://beta.nextjs.org/docs/optimizing/images#remote-images
Optimizing: Images | Next.js
Using App Router Features available in /app
nextjs.org
# react map
product.map((item: string, index: number)=> {
return(
// 소스
)
})
참고 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Array.prototype.map() - JavaScript | MDN
map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.
developer.mozilla.org
- for 문법의 경우 html 바깥에서 for 써서 결과를 array에 담은 후에 그 결과를 html에 집어넣는 식으로는 가능하기 때문에 리액트에서는 map을 많이 사용한다. (map은 하두 이전에 써서 설명하지않음)
+++ 빠진 설명은 이전에 리액트 공부를 너무 많이 했기에 생략한다.
+++ 드디어 회사에서 뷰를 쓰다가 리액트로 넘어간다고 한다.
+++ 빛을 발휘할 기회이니 열심히 준비하자! 화이팅😚
'React' 카테고리의 다른 글
next13 (feat. 애플코딩,MongoDB) (0) | 2024.01.04 |
---|---|
vercel로 next13 배포 (0) | 2024.01.03 |
react를 공부하고 있는 중급자(?)를 위한 tip (0) | 2023.08.24 |
리액트 아코디언 메뉴(feat.Gnb) (2) | 2023.05.15 |
react + tailwind (0) | 2023.05.12 |