Search

State

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
๋ณต์‚ฌ