
component
cart/page.js
export default function Cart() {
return (
<div>
<h4 className="title">Cart</h4>
<div className="cart-item">
<p>์ํ๋ช
</p>
<p>$40</p>
<p>1๊ฐ</p>
</div>
<div className="cart-item">
<p>์ํ๋ช
</p>
<p>$40</p>
<p>1๊ฐ</p>
</div>
</div>
);
}
์ด๋ ๊ฒ ์๊ธด cart-item ํ๋๋ฅผ ์ปดํฌ๋ํธ๋ก ๋ง๋ค์ด ์ฝ๊ฒ ๋ฐ๋ณต ์ฌ์ฉํ ์ ์๋ค.
function CartItem() {
return (
<div className="cart-item">
<p>์ํ๋ช
</p>
<p>$40</p>
<p>1๊ฐ</p>
</div>
);
}
์ด๋ ๊ฒ ๋ง๋ค์ด์ฃผ๊ณ ,
export default function Cart() {
return (
<div>
<h4 className="title">Cart</h4>
<CartItem />
<CartItem />
<CartItem />
</div>
);
}
์ด๋ ๊ฒ ์ถ๊ฐํด์ฃผ๋ฉด

์ํ๋ ๊ฐ์๋งํผ ์์ฑํ ์๊ฐ ์๋ค.
server component
์์ ๋ง๋ ๊ฒ์ฒ๋ผ ์๋ฌด๋ฐ๋ ๋์ถฉ ๋ง๋ ๊ฑด server component๊ฐ ๋๋ค.
server component๋ html์์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ธฐ๋ฅ(์๋ฅผ ๋ค๋ฉด onClick={}๊ฐ์..)์ ๋ฃ์ ์๊ฐ ์๋ค.
useEffect, useState ๋ฑ์ ์ฌ์ฉํ ์ ์๋ค.

Error: Event handlers cannot be passed to Client Component props.
<button onClick={function} children=...>
If you need interactivity, consider converting part of this to a Client Component.
๊ทผ๋ฐ ์ server component ๋ถํธํ๊ฒ ์ฐ๋? ์ฅ์ ์ด ์์ผ๋๊น!
์ผ๋จ ๋ก๋ฉ์ด ๋น ๋ฅด๋น ๊ฒ์์์ง ๋
ธ์ถ ๋ฑ์๋ ์ ๋ฆฌํ๋ค.
client component
server component์ ๋ค๋ฅด๊ฒ ํ์ผ ์๋จ์ 'use client'๋ผ๊ณ ์ฐ๊ณ ๋ง๋ ๊ฑด, client component๊ฐ ๋๋ค.
client component ์์์๋ html ๋ด ์๋ฐ์คํฌ๋ฆฝํธ ๊ธฐ๋ฅ์ด๋ผ๋ ์ง, useEffect, useState ๋ฑ์ ์ฌ์ฉํ ์ ์๋ค.
client component๋ ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๋ง์ด ํ์ํด ๋ก๋ฉ ์๋๊ฐ ๋๋ฆฌ๊ณ , ๋ hydration์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ๋ ๋๋ฆฌ๋ค.
hydration : html ์ ์ ์๊ฒ ๋ณด๋ธ ํ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ก html ๋ค์ ์ฝ๊ณ ๋ถ์ํ๋ ์ผ
๊ฒฐ๋ก
ํฐ ํ์ด์ง๋ server component,
์๋ฐ์คํฌ๋ฆฝํธ ๊ธฐ๋ฅ๋ค์ด ํ์ํ ํ์ด์ง์๋ง client component๋ฅผ ์ด์ฉ!
๋ณ์ ๊ฐ์ ธ์ค๊ธฐ ๐ฉ
๋ค๋ฅธ ํ์ผ์์ ์์ฑํ ๋ณ์๋ฅผ ๊ฐ์ ธ์ ๋ณด์!
data.js
let age = 20;
export default age;
cart/page.js
import age from "./data";
...
<p>์ํ๋ช
{age}</p>
...
import์ export๋ฅผ ์ ์ ํ ํด์ฃผ๋ฉด ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
๋ณ์๊ฐ 2๊ฐ ์ด์์ผ ๋
data.js
let price = 20;
let name = "๋ฐ๋๋";
export { price, name };
export ํ๊ณ ์ถ์ ๋ณ์๊ฐ ๋ ๊ฐ ์ด์์ด๋ฉด, ์ค๊ดํธ{}๋ฅผ ์ฌ์ฉํ์ฌ export ํ๋ค.
cart/page.js
import { price, name } from "./data";
...
<div className="cart-item">
<p>{name}</p>
<p>${price}</p>
<p>1๊ฐ</p>
</div>
...
๊ทธ๋ฆฌ๊ณ ๋ถ๋ฌ์ฌ ๋๋ ์ค๊ดํธ๋ฅผ ์ฌ์ฉํด ์ค๋ค.

Props
cart/page.js
export default function Cart() {
let shoppingCart = ["Tomatoes", "Pasta"];
...
์ํ์ data๋ฅผ ํ๋ ๋ง๋ค์ด์ฃผ๊ณ , ์ด๋ฅผ ์ถ๋ ฅํ๊ณ ์ถ์ผ๋ฉด
์๊น ๋ง๋ค์๋ ์ปดํฌ๋ํธ์์ {product[0]}๋ฅผ ํด์ฃผ๋ฉด ๋ ๊ฒ ๊ฐ์ง๋ง,
fucntion์์ ๋ง๋ ๋ณ์๋ ๊ทธ ํจ์ ๋ด์์๋ง ์ฌ์ฉํ ์ ์๋ค.
๋ถ๋ชจ์ปดํฌ๋ํธ->์์์ปดํฌ๋ํธ๋ก ๋ณ์๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ผ๋ฉด props๋ฅผ ์ด์ฉํด์ฃผ๊ธฐ!
<CartItem product={shoppingCart[0]}/>
// <์์์ปดํฌ๋ํธ ์๋ช
={์ ํด์ค๋ฐ์ดํฐ} />
...
function CartItem(props) {
return (
<div className="cart-item">
<p>{props.product}</p>
<p>${price}</p>
<p>1๊ฐ</p>
</div>
);
}
์ด๋ ๊ฒ ํด์ฃผ๋ฉด

์ ๊ฐ์ ธ์ฌ ์ ์์.
- props๋ <CartItem ์ด๋ฐ๊ฑฐ={์ด๋ฐ๊ฑฐ} ์ ๋ฐ๊ฑฐ={์ ๋ฐ๊ฑฐ}> ์ด๋ ๊ฒ ๋ง์ด ์ ์ก๊ฐ๋ฅ
- ์ผ๋ฐ ๋ฌธ์๋ฐ์ดํฐ ์ ์กํ๋ ค๋ฉด ์ค๊ดํธ ์์ด <CartItem ์ด์ฉ๊ตฌ="์ด์ฉ๊ตฌ"> ํด๋ ๊ฐ๋ฅ
์๋ ๋ฒํผ โ๏ธ
list/page.js
let [count, setCount] = useState(0);
useState๋ฅผ ์ด์ฉํด์ ๋ณ์์ ๋ด์์คฌ๋ค.
์ผ๋ฐ๋ณ์๋ ๋ณ๊ฒฝ๋์ด๋ ๋ณ์๊ฐ ๋ค์ด์๋ html์ ์๋์ผ๋ก ๋ฐ์๋์ง ์์ผ๋, state๊ฐ ๋ณ๊ฒฝ๋๋ฉด state๊ฐ ๋ค์ด์๋ html๋ ์๋์ผ๋ก ์ฌ๋ ๋๋ง์ด ๋๋ค.
์์์ ์ค๋ช ํ๋ฏ ์๋จ์
"use client";
๋ฅผ ๊ผญ ์จ์ฃผ์ด์ผ ํจ! ์๋๋ฉด useState๋ client component์์๋ง ์ธ ์ ์๊ธฐ ๋๋ฌธ!
๊ทธ๋ฆฌ๊ณ ๋ฒํผ์ onClick ํจ์๋ฅผ ์ถ๊ฐํด ํ๋ฉด์ ์๋ + - ๊ฐ ์คํ๋๊ฒ ํด์ฃผ์๋ค.
<button
onClick={() => {
count <= 0
? (0, alert("๋ ์ค์ผ ์ ์์ต๋๋ค!"))
: setCount(count - 1);
}}
>
-
</button>
<span>{count}</span>
<button
onClick={() => {
setCount(count + 1);
}}
>
+
</button>

map์ผ๋ก ํ๋๋ ์๋ค ํ๋ ๋๋ฅด๋๊น ๋๋จธ์ง ๋ค ๋๋ฌ์ง๋ค...
์ด๊ฑฐ ์ด๋ฐ์์ผ๋ก ์ฅ์ฌํ๋ฉด ์ ์ฌ๊ธฐ๊พผ์ด ๋๋ ์์ ํด์ฃผ์ด์ผ ํจ.
๊ทธ๋ฌ๋ ค๋ฉด ์ผ๋จ state ๋ถํฐ ๊ฐ๊ฐ ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค.
ํ์ง๋ง ๊ทธ๋ฌ๋ฉด ๊ท์ฐฎ์ผ๋ ์ด๋ ๊ฒ ํด๋ณด๋๋ก ํจ.
let [count, setCount] = useState([0, 0, 0]);
๊ฒฐ๊ณผ
{grocery.map((a, i) => {
return (
<div className="food" key={i}>
<img src={"food" + i + ".png"} className="food-img" width={50} />
<h4>{a} $40</h4>
<button
onClick={() => {
let copy = [...count];
count <= 0
? (0, alert("๋ ์ค์ผ ์ ์์ต๋๋ค!"))
: (copy[i]++, setCount(copy));
}}
>
-
</button>
<span> {count[i]} </span>
<button
onClick={() => {
let copy = [...count];
copy[i]++;
setCount(copy);
}}
>
+
</button>
</div>
);
})}
state๋ฅผ ...๋ฌธ๋ฒ(spread operator)์ผ๋ก ๋ณต์ฌํ๊ณ state์ [i]๋ฒ ํญ๋ชฉ์ +1 ํด์ค ๋ค์ setCount๋ก ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
spread operator
์ ...๋ฅผ ์ด์ฉํด์ ๋ณต์ฌ๋ฅผ ๋จผ์ ํ๋๋ฉด, set์ด์ฉ๊ตฌ()๋ฅผ ํ๊ฒ ๋๋ฉด ์ปดํจํฐ๋ ๊ธฐ์กดstate์ ์ ๊ทstate์ ์ผ์น์ฌ๋ถ ๋ถํฐ ๊ฒ์ฌํด๋ณธ๋ค.
๊ฒ์ํด๋ณด๊ณ ๊ฐ์ผ๋ฉด state๋ฅผ ๋ณ๊ฒฝํด์ฃผ์ง ์์.
๊ทธ๋ฌ๋๊น,
count[0]++
setCount[count]
์ด๋ ๊ฒ ํด๋ดค์ ๋ณต์ฌํด์ฃผ์ง ์๋๋ค๋ ๊ฒ์ด๋ค.
++๋ฅผ ํ๋๋ฐ ์?.?
array/object์๋ฃ๋ฅผ let arr = [1,2,3] ์๋ฐ์์ผ๋ก ํ๋ ๋ง๋ค๋ฉด
RAM์๋ค๊ฐ ๋ชฐ๋ ์ ์ฅ์ด ๋๊ณ , let arr ๋ณ์๋ ๊ทธ ์๋ฃ๊ฐ ์ด๋์๋ ๊ฑฐ๋ค~ ํ๋ ํ์ดํ๋ง ๋ด๊ฒจ์๋ ๊ฒ์ด๋ค.
๊ทธ๋ฌ๋ ๊ทธ ์๋ฃ๋ฅผ ์์ ํ๋ค๊ณ ํด์ ํ์ดํ๋ฅผ ํ๊ณ ๋ค์ด๊ฐ RAM๊ฐ์ด ์์ ๋ ๋ฟ ๊ทธ ๋ณ์์ ๋ด๊ธด ํ์ดํ๋ ๋ณํ์ง ์๊ธฐ ๋๋ฌธ์,
๊ธฐ์กดstate์ ์ ๊ทstate๋ฅผ ๋น๊ตํ๋ฉด (==๋ก ๋น๊ตํ๊ธฐ ๋๋ฌธ์) ๋ณ์์ ์ ์ฅ๋ ํ์ดํ๋ง ๋น๊ตํด์ฃผ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ค๊ณ ๋์ค๋ ๊ฒ์ด๋ค.
let arr = [1,2,3]
let arr2 = arr
arr2[0]++
arr์ ์๋ ๊ฑธ arr2์ ๋ณต์ฌ๋ฅผ ํ๋ค๊ณ ํด๋ ํ์ดํ๋ง ๋ณต์ฌ๋ ๋ฟ์ด๋ผ,
์ฝ์์ฐฝ์ ์
๋ ฅํด๋ณด๋ฉด
++ ๋ ๊ฐ์ด ์๋ ๊ทธ๋๋ก 1์ด ์ถ๋ ฅ๋ ๋ฟ๋๋ฌ
arr == arr2 ๋ true๊ฐ ๋์จ๋ค.
์ฐธ๊ณ : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
๊ทผ๋ฐ ์ฌ๊ธฐ์ ๋ง์ฝ์ ์คํ๋ ๋ ์ฐ์ฐ์๋ฅผ ์ด์ฉํ๋ฉด,
let arr = [1,2,3]
undefined
let arr2 = [...arr]

์์ ๋
๋ฆฝ์ ์ธ ๋ณต์ฌ๋ณธ์ ์์ฑํด์ฃผ๋ ๊ฒ~
๊น์ ๋ณต์ฌ์์ ์์ธํ ์์๋ณผ ์ ์๋ ๋ถ๋ถ์ด๋ค.
์๋ฌดํผ ์ด๋ ๊ฒ ํด์ฃผ์๋๋ฐ 0 ์ดํ๋ก ๋ด๋ ค๊ฐ์ ๋ ๊ฐ์๊ฐ -๊ฐ ๋์๋ค.
์ฒ์์ ์ผํญ์ฐ์ฐ์์์ ๊ฐ๋จํ copy๋ถ๋ถ๋ง ์์ ํด์ค์
0 ์ผ๋ก ์
๋ ฅํ๋๊ฒ ์ฌ์ค์ ์๋ฌด ์๋ฏธ๊ฐ ์๊ฒ ๋ ๊ฒ.
์ผํญ์ฐ์ฐ์๋ฅผ ๋ฏ์ด๊ณ ์ณ์ผ ํ๋ค.
<button
onClick={() => {
let copy = [...count];
copy[i] <= 0
? ((copy[i] = 0), alert("๋ ์ค์ผ ์ ์์ต๋๋ค!"))
: (copy[i]--, setCount(copy));
}}
>
-
</button>

'TIL > Next.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Next.js | ๋ค์ด๋ฒ ๋ก๊ทธ์ธ ๊ตฌํํ๊ธฐ (๋ค์๋ก~) (0) | 2024.03.06 |
---|---|
Next.js | ๊ตฌ๊ธ ๋ก๊ทธ์ธ ๊ตฌํํ๊ธฐ (0) | 2024.03.05 |
Next.js | ์นด์นด์ค ๋ก๊ทธ์ธ ๊ตฌํํ๊ธฐ (1) | 2024.02.27 |
[TIL] Next.js 13 ๋ผ์ฐํ (4) | 2023.05.27 |
Next.js ๊ธฐ์ด 1 - ์์ํ๊ธฐ & ๋ผ์ฐํ & ์ด๋ฏธ์ง ๋ฃ๊ธฐ (0) | 2023.05.20 |