State (μν)
μ»΄ν¬λνΈκ° κ΄λ¦¬νλ λ‘컬(λ΄λΆ) λ°μ΄ν°
React μ»΄ν¬λνΈμ μν(State)λ μ»΄ν¬λνΈκ° κ΄λ¦¬νλ λ‘컬 λ°μ΄ν°μ
λλ€. μνλ₯Ό μ¬μ©νλ©΄ μ»΄ν¬λνΈκ° λμ μΈ λ°μ΄ν°λ₯Ό μ μ₯νκ³ νμν μ μμΌλ©°, μνκ° λ³κ²½λ λλ§λ€ Reactλ μλμΌλ‘ νλ©΄μ λ€μ λ λλ§ν©λλ€.
State μ νΉμ§
1.
μν μ΄κΈ°ν
: μ»΄ν¬λνΈκ° μμ±λ λ useState ν
μ΄λ ν΄λμ€ μ»΄ν¬λνΈμ constructor λ©μλμμ μ΄κΈ° μνλ₯Ό μ€μ ν©λλ€.
2.
μν μ
λ°μ΄νΈ
: setCountλ this.setStateλ₯Ό μ¬μ©νμ¬ μνλ₯Ό μ
λ°μ΄νΈν©λλ€. μ΄λ μ΄μ μνλ₯Ό μ°Έμ‘°νμ¬ λ³κ²½μ μ§ννλ κ²μ΄ μ€μν©λλ€.
3.
μ»΄ν¬λνΈλ³λ‘ κ³ μ ν μν
: κ°κ°μ μΈμ€ν΄μ€λ μ체 μνλ₯Ό μ μ§νλ―λ‘, λμΌν μ»΄ν¬λνΈμ μ¬λ¬ μΈμ€ν΄μ€ κ°μλ κ°κ° λ
립μ μΈ μνκ° μ‘΄μ¬ν©λλ€.
μ€μ΅ μ½λ
βμν μμΈ UI λ§λ€κΈ° - stateβ
βμν μμΈ UI λ§λ€κΈ° - stateβ μμλ 1~3λ¨κ³λ‘ λλμ΄ μ€μ΅ν©λλ€.
1λ¨κ³ - JSX λ¬Έλ²λ§μ μ¬μ©νμ¬ ProductDetail.jsx μ»΄ν¬λνΈλ₯Ό μ μ 컨ν
μΈ λ‘ λμμΈν©λλ€.
2λ¨κ³ - JavaScript κ°μ²΄λ₯Ό μ¬μ©νμ¬, λμ μΌλ‘ μν μμΈ μ 보λ₯Ό λλλ§ ν©λλ€.
3λ¨κ³ - quantity (μλ) μ μν(state) λ‘ μ μνμ¬, , λ²νΌμ λλ¬ μ΄λ²€νΈ μ²λ¦¬λ₯Ό νκ³ , μνλ³νμ λ°λΌ 리λλλ§νλ κ³Όμ μ νμΈν©λλ€.
μμ ν νμΌ
β’
componets/ProductDetail.jsx
β’
App.js
β’
App.css
1λ¨κ³
JSX λ¬Έλ²λ§μ μ¬μ©νμ¬ ProductDetail.jsx μ»΄ν¬λνΈλ₯Ό μ μ 컨ν
μΈ λ‘ λμμΈν©λλ€
β’
componets/ProductDetail.jsx
β’
App.js
β’
App.css
μ»΄ν¬λνΈ κ΅¬μ‘°
β’
App
β¦
ProductDetail
App, ProductDetail μ»΄ν¬λνΈ
componets/ProductDetail.jsx
import React from 'react'
const ProductDetail = () => {
return (
<div className='product-detail'>
<div className="item img">
<img src="https://i.imgur.com/1vpSkbW.png" alt="μνλͺ
" />
</div>
<div className="item info">
<div className="title">
<h1>μνλͺ
</h1>
</div>
<p>
<span className='txt-pt'>INFO</span><br />
-νΈμν μ°©μ©μ΄ κ°λ₯ν ν΄λΌ λμμΈ <br />
-체ν 컀λ²κ° κ°λ₯ν λ² μ΄μ§ν μ€λ£¨μ£ <br />
</p>
<p>
<span className="txt-pt">Color & Size</span> <br />
Black, Navy, Red <br />
85, 90, 95, 100, 110 <br />
- μ΄κΉ¨ 53, κ°μ΄ 59, μν 23, μ맀 62, μ΄μ₯ 68 <br />
(μΈ‘μ λ°©λ²μ λ°λΌ 1~3cm μ€μ°¨κ° μμ μ μμ΅λλ€) <br />
</p>
<span className='line-lg'></span>
<div className="text-group">
<div className="item">
<span className='txt-pt'>ν맀κ°</span>
</div>
<div className="item">
<span className='txt-pt'>42,000 μ</span>
</div>
</div>
<div className="text-group">
<div className="item">
<span>λ°°μ‘λΉ</span>
</div>
<div className="item">
<span>3,000</span> μ
</div>
</div>
<span className="line-lg"></span>
<div className="text-group">
<div className="item">
<span>Color</span>
</div>
<div className="item">
<select name="color" id="color">
<option value="Black">Black</option>
<option value="Navy">Navy</option>
<option value="Red">Red</option>
</select>
</div>
</div>
<div className="text-group">
<div className="item">
<span>Size</span>
</div>
<div className="item">
<select name="color" id="color">
<option value="85">85</option>
<option value="90">90</option>
<option value="95">95</option>
<option value="100">100</option>
<option value="110">110</option>
</select>
</div>
</div>
<div className="text-group">
<div className="item">
<span>μλ</span>
</div>
<div className="item flex">
<input type="text" className='quantity' min={1} max={100} value={1} />
<button className='btn btn-xs'>+</button>
<button className='btn btn-xs'>-</button>
</div>
</div>
<span className="line-lg"></span>
<div className="text-group">
<div className="item">
<span className='txt-pt'>μ΅μ’
κ°κ²©</span>
</div>
<div className="item">
<span className='txt-pt'>42,000</span>
</div>
</div>
<div className="text-group flex gap-1">
<div className="item">
<button className="btn btn-lg">ꡬ맀νκΈ°</button>
</div>
<div className="item flex">
<button className="btn btn-lg btn-outline">μ₯λ°κ΅¬λ</button>
<button className="btn btn-lg btn-outline">κ΄μ¬μν</button>
</div>
</div>
</div>
</div>
)
}
export default ProductDetail
JavaScript
볡μ¬
App.js
import logo from './logo.svg';
import './App.css';
import ProductDetail from './components/ProductDetail';
function App() {
return (
<div>
<ProductDetail />
</div>
);
}
export default App;
JavaScript
볡μ¬
App.css
.txt-pt {
color: salmon;
font-weight: bold;
}
.line-lg {
display: block;
border-bottom: 2px solid lightgray;
}
.product-detail {
display: inline-flex;
justify-content: center;
column-gap: 100px;
padding: 10px;
/* border: 1px solid salmon; */
}
.product-detail .item {
width: 400px;
}
.product-detail .info {
border-top: 2px solid black;
border-bottom: 2px solid black;
}
.quantity {
width: 40px;
font-size: 16px;
line-height: 20px;
height: 20px;
text-align: center;
appearance: none;
}
/* κ³΅ν΅ */
.text-group {
display: flex;
padding: 10px 0;
}
img { width: 100%; }
select {
width: 100%;
font-size: 16px;
line-height: 40px;
height: 40px;
padding-left: 15px;
padding-right: 15px;
color: #222;
color: inherit;
cursor: pointer;
outline: none;
border: 1px solid #777;
background: none;
border-radius: 0;
padding-right: 32px;
}
.flex {
display: flex;
}
.flex.gap-1 {
gap: 10px;
}
.btn {
background-color: royalblue;
color: white;
font-weight: bold;
outline: none;
border: none;
margin: 0 2px;
padding: 0 10px;
cursor: pointer;
}
.btn:hover {
box-shadow: 2px 2px 2px rgba(0,0,0,0.5);
}
.btn:active {
box-shadow: none;
}
.btn.btn-lg {
width: 100%;
min-height: 40px;
}
.btn.btn-outline {
border: 2px solid gray;
background-color: white;
color: gray;
}
CSS
볡μ¬
2λ¨κ³
JavaScript κ°μ²΄λ₯Ό μ¬μ©νμ¬, λμ μΌλ‘ μν μμΈ μ 보λ₯Ό λλλ§ ν©λλ€.
β’
componets/ProductDetail.jsx
μ»΄ν¬λνΈ κ΅¬μ‘°
β’
App
β¦
ProductDetail
App, ProductDetail μ»΄ν¬λνΈ
componets/ProductDetail.jsx
import React, { useState } from 'react'
const ProductDetail = (props) => {
// β
κ°μ²΄ μΆκ°
const product = {
productId : 'p000001',
name : 'λ² μ΄μ§ ν΄λΌ λνΈ',
price : 42000,
quantity : 1,
img: 'https://i.imgur.com/1vpSkbW.png',
}
// β
μ΅μ’
κ°κ²© κ³μ°
const totalPrice = product.price * product.quantity
return (
<div className='product-detail'>
<div className="item img">
<img src={product.img} alt={product.name} />
</div>
<div className="item info">
<div className="title">
<h1>{product.name}</h1>
</div>
<p>
<span className='txt-pt'>INFO</span><br />
-νΈμν μ°©μ©μ΄ κ°λ₯ν ν΄λΌ λμμΈ <br />
-체ν 컀λ²κ° κ°λ₯ν λ² μ΄μ§ν μ€λ£¨μ£ <br />
</p>
<p>
<span className="txt-pt">Color & Size</span> <br />
Black, Navy, Red <br />
85, 90, 95, 100, 110 <br />
- μ΄κΉ¨ 53, κ°μ΄ 59, μν 23, μ맀 62, μ΄μ₯ 68 <br />
(μΈ‘μ λ°©λ²μ λ°λΌ 1~3cm μ€μ°¨κ° μμ μ μμ΅λλ€) <br />
</p>
<span className='line-lg'></span>
<div className="text-group">
<div className="item">
<span className='txt-pt'>ν맀κ°</span>
</div>
<div className="item">
<span className='txt-pt'>{product.price.toLocaleString()} μ</span>
</div>
</div>
<div className="text-group">
<div className="item">
<span>λ°°μ‘λΉ</span>
</div>
<div className="item">
<span>3,000</span> μ
</div>
</div>
<span className="line-lg"></span>
<div className="text-group">
<div className="item">
<span>Color</span>
</div>
<div className="item">
<select name="color" id="color">
<option value="Black">Black</option>
<option value="Navy">Navy</option>
<option value="Red">Red</option>
</select>
</div>
</div>
<div className="text-group">
<div className="item">
<span>Size</span>
</div>
<div className="item">
<select name="color" id="color">
<option value="85">85</option>
<option value="90">90</option>
<option value="95">95</option>
<option value="100">100</option>
<option value="110">110</option>
</select>
</div>
</div>
<div className="text-group">
<div className="item">
<span>μλ</span>
</div>
<div className="item flex">
<input type="text" className='quantity' value={product.quantity} min={1} max={100} />
<button className='btn btn-xs'>+</button>
<button className='btn btn-xs'>-</button>
</div>
</div>
<span className="line-lg"></span>
<div className="text-group">
<div className="item">
<span className='txt-pt'>μ΅μ’
κ°κ²©</span>
</div>
<div className="item">
<span className='txt-pt'>{totalPrice.toLocaleString()} μ</span>
</div>
</div>
<div className="text-group flex gap-1">
<div className="item">
<button className="btn btn-lg">ꡬ맀νκΈ°</button>
</div>
<div className="item flex">
<button className="btn btn-lg btn-outline">μ₯λ°κ΅¬λ</button>
<button className="btn btn-lg btn-outline">κ΄μ¬μν</button>
</div>
</div>
</div>
</div>
)
}
export default ProductDetail
JavaScript
볡μ¬
3λ¨κ³
quantity (μλ) μ μν(state) λ‘ μ μνμ¬, , λ²νΌμ λλ¬ μ΄λ²€νΈ μ²λ¦¬λ₯Ό νκ³ , μνλ³νμ λ°λΌ 리λλλ§νλ κ³Όμ μ νμΈν©λλ€.
β’
componets/ProductDetail.jsx
μ»΄ν¬λνΈ κ΅¬μ‘°
β’
App
β¦
ProductDetail
App, ProductDetail μ»΄ν¬λνΈ
componets/ProductDetail.jsx
import React, { useState } from 'react'
const ProductDetail = (props) => {
// β
state μΆκ°
const [quantity, setQuantity] = useState(1)
// β
κ°μ²΄ μΆκ°
const product = {
productId : 'p000001',
name : 'λ² μ΄μ§ ν΄λΌ λνΈ',
price : 42000,
quantity : 1,
img: 'https://i.imgur.com/1vpSkbW.png',
}
// β
μ΅μ’
κ°κ²© κ³μ°
const totalPrice = product.price * quantity
// β
μ΄λ²€νΈ μ μ - μ¦κ°
const onIncrease = () => {
console.log(quantity);
setQuantity(quantity + 1)
}
// β
μ΄λ²€νΈ μ μ - κ°μ
const onDecrease = () => {
console.log(quantity);
setQuantity(quantity - 1)
}
return (
<div className='product-detail'>
<div className="item img">
<img src={product.img} alt={product.name} />
</div>
<div className="item info">
<div className="title">
<h1>{product.name}</h1>
</div>
<p>
<span className='txt-pt'>INFO</span><br />
-νΈμν μ°©μ©μ΄ κ°λ₯ν ν΄λΌ λμμΈ <br />
-체ν 컀λ²κ° κ°λ₯ν λ² μ΄μ§ν μ€λ£¨μ£ <br />
</p>
<p>
<span className="txt-pt">Color & Size</span> <br />
Black, Navy, Red <br />
85, 90, 95, 100, 110 <br />
- μ΄κΉ¨ 53, κ°μ΄ 59, μν 23, μ맀 62, μ΄μ₯ 68 <br />
(μΈ‘μ λ°©λ²μ λ°λΌ 1~3cm μ€μ°¨κ° μμ μ μμ΅λλ€) <br />
</p>
<span className='line-lg'></span>
<div className="text-group">
<div className="item">
<span className='txt-pt'>ν맀κ°</span>
</div>
<div className="item">
<span className='txt-pt'>{product.price.toLocaleString()} μ</span>
</div>
</div>
<div className="text-group">
<div className="item">
<span>λ°°μ‘λΉ</span>
</div>
<div className="item">
<span>3,000</span> μ
</div>
</div>
<span className="line-lg"></span>
<div className="text-group">
<div className="item">
<span>Color</span>
</div>
<div className="item">
<select name="color" id="color">
<option value="Black">Black</option>
<option value="Navy">Navy</option>
<option value="Red">Red</option>
</select>
</div>
</div>
<div className="text-group">
<div className="item">
<span>Size</span>
</div>
<div className="item">
<select name="color" id="color">
<option value="85">85</option>
<option value="90">90</option>
<option value="95">95</option>
<option value="100">100</option>
<option value="110">110</option>
</select>
</div>
</div>
<div className="text-group">
<div className="item">
<span>μλ</span>
</div>
<div className="item flex">
<input type="text" className='quantity' value={quantity} min={1} max={100} /> {/* value λ₯Ό state λ‘ λ³κ²½ */}
<button className='btn btn-xs' onClick={ onIncrease }>+</button> {/* μ΄λ²€νΈ μΆκ° */}
<button className='btn btn-xs' onClick={ onDecrease }>-</button> {/* μ΄λ²€νΈ μΆκ° */}
</div>
</div>
<span className="line-lg"></span>
<div className="text-group">
<div className="item">
<span className='txt-pt'>μ΅μ’
κ°κ²©</span>
</div>
<div className="item">
<span className='txt-pt'>{totalPrice.toLocaleString()} μ</span>
</div>
</div>
<div className="text-group flex gap-1">
<div className="item">
<button className="btn btn-lg">ꡬ맀νκΈ°</button>
</div>
<div className="item flex">
<button className="btn btn-lg btn-outline">μ₯λ°κ΅¬λ</button>
<button className="btn btn-lg btn-outline">κ΄μ¬μν</button>
</div>
</div>
</div>
</div>
)
}
export default ProductDetail
JavaScript
볡μ¬