React

์ฒœ๋ฌธ์„ฑยท2023๋…„ 2์›” 4์ผ
0

๐Ÿ’ก ๋ฆฌ์•กํŠธ์—์„  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ๋‹ค๋ฅด๊ฒŒ state๋ฅผ ํ™œ์šฉ (ํ•ญ์ƒ state๋ฅผ ์กฐ์ž‘)

๋ฆฌ์•กํŠธ ์‚ฌ์šฉ ์ด์œ  : ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ / html์„ ํ•จ์ˆ˜,array, object์— ๋ณด๊ด€ํ•˜๊ณ  ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ(html๊ด€๋ฆฌ ํŽธํ•จ) / react native๋ฅผ ํ†ตํ•ด ๊ฐ™์€ ๋ฆฌ์•กํŠธ ๋ฌธ๋ฒ•์œผ๋กœ ๋ชจ๋ฐ”์ผ์•ฑ๊ฐœ๋ฐœ ๊ฐ€๋Šฅ(html css๋ฌธ๋ฒ•๋งŒ ์•ฝ๊ฐ„ ๋‹ค๋ฆ„)

๊ฐœ๋ฐœํ™˜๊ฒฝ ์„ธํŒ…

nodejs์„ค์น˜ โ†’ ์ž‘์—…ํด๋”์ƒ์„ฑ ํ›„ ํ„ฐ๋ฏธ๋„์—ด์–ด์„œ npx create-react-app ํ”„๋กœ์ ํŠธ๋ช… โ†’vscode์—์„œ ์—ด๊ธฐ

scrํด๋” ์•ˆ์˜ App.js์—์„œ ์ฝ”๋“œ์ž‘์„ฑ โ†’ vscodeํ„ฐ๋ฏธ๋„์—์„œ npm start๋ˆ„๋ฅด๋ฉด ์ž‘์„ฑํ•œ ํŽ˜์ด์ง€ ๋ณด์—ฌ์คŒ

์ปจํŠธ๋กค+c ๋ˆ„๋ฅด๋ฉด ์ข…๋ฃŒ

๊ธฐ์กด html css์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์งœ์ง€๋งŒ ๋ฆฌ์•กํŠธ์—์„œ๋Š” html๋Œ€์‹  JSX๋ผ๋Š”๊ฑธ ์‚ฌ์šฉ

์›นํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ์€ html์—์„œ ์งœ๋˜๊ฒƒ์ฒ˜๋Ÿผ div๋ฐ•์Šค๋กœ ๋‚˜๋ˆ ์„œ ์‚ฌ์šฉ

css์Šคํƒ€์ผ์€ App.cssํŒŒ์ผ์—์„œ ์ž‘์„ฑ

๐Ÿ“Œ JSX ๋ฌธ๋ฒ•

  • html์— class๋„ฃ์„๋• className์‚ฌ์šฉ

JSX๋Š” ์ผ์ข…์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ผ์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์•ฝ์–ด์ธ class๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋จ

  • ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ - ๋ณ€์ˆ˜๋ฅผ html์— ๊ฝ‚์•„๋„ฃ์„๋•Œ๋Š” {๋ณ€์ˆ˜๋ช…} ์ค‘๊ด„ํ˜ธ์‚ฌ์šฉ, ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜ฌ๋•Œ๋„ ๋™์ผ

href / id / className / src ๋“ฑ ์—ฌ๋ผ๊ฐ€์ง€ html์†์„ฑ๋“ค์— ๋„ฃ์–ด์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅ

โ‡’๋ณ€์ˆ˜์— ์žˆ๋˜๊ฑธ html์— ๊ฝ‚์•„๋„ฃ๋Š” ์ž‘์—…์„ ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ ์ด๋ผ๊ณ  ํ•จ

  • html์— style์†์„ฑ์„ ๋ฐ”๋กœ ๋„ฃ๊ณ ์‹ถ์„๋•Œ

style={}์•ˆ์— {}์ž๋ฃŒํ˜•์œผ๋กœ ์ง‘์–ด๋„ฃ์–ด์•ผํ•จ - {์†์„ฑ๋ช… : โ€˜์†์„ฑ๊ฐ’โ€™}

font-size์ฒ˜๋Ÿผ ๋Œ€์‰ฌ๊ธฐํ˜ธ ์‚ฌ์šฉ ๋ถˆ๊ฐ€ โ†’ ์ผ์ข…์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋นผ๊ธฐ๋กœ ์ธ์‹ , ๋ถ™์—ฌ์„œ ์•ž๊ธ€์ž๋ฅผ ๋Œ€๋ฌธ์ž๋กœ

function App() {

  let post = '๋ง›์ง‘ํˆฌ์–ด';

  return (
    <div className="App">
      <div className="black-nav">
				//์ด๋Ÿฌ๋ฉด ํด๋ž˜์Šค๋ช…์ด ๋ง›์ง‘ํˆฌ์–ด๊ฐ€ ๋จ
        <h4 className={post} style={{color: 'yellow', fontSize: '16px'}}>BLOG</h4>
      </div>
      <h4>{post}</h4>
    </div>
  );
}

state ๋งŒ๋“œ๋Š” ๋ฒ•

์ œ์ผ ์œ„์— import {useState} from โ€˜reactโ€™ ํ•˜๊ณ 

useState(โ€™๋ณด๊ด€ํ• ์ž๋ฃŒโ€™) : ์ž๋ฃŒ ์ €์žฅ๊ฐ€๋Šฅ

let [a,b] = useState(โ€™๋‚จ์ž์ฝ”ํŠธ์ถ”์ฒœโ€™); โ†’ a์ž๋ฆฌ์— state์ด๋ฆ„์„ ์ž‘๋ช…ํ•˜๊ณ  ์‚ฌ์šฉ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ destructuring ๋ฌธ๋ฒ•

array์•ˆ์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋“ค์„ ๋ณ€์ˆ˜๋กœ ์‰ฝ๊ฒŒ ์ €์žฅํ•˜๊ณ  ์‹ถ์„๋•Œ ์“ฐ๋Š” ๋ฌธ๋ฒ•

let [name, age] = ['Kim', 20] //name์—๋Š” Kim, age์—๋Š” 20

โ‡’ ๋ฆฌ์•กํŠธ์—์„œ๋Š” useState()๋ฅผ ์“ฐ๋ฉด [๋ฐ์ดํ„ฐ1, ๋ฐ์ดํ„ฐ2] ํ˜•ํƒœ์˜ array๊ฐ€ ๋‚จ์Œ

๋ฐ์ดํ„ฐ1์ž๋ฆฌ์—” โ€˜๋‚จ์ž์ฝ”ํŠธ์ถ”์ฒœโ€™๊ฐ™์€ ์ž๋ฃŒ๊ฐ€ ์žˆ๊ณ 

๋ฐ์ดํ„ฐ2์ž๋ฆฌ์—” state๋ณ€๊ฒฝ์„ ๋„์™€์ฃผ๋Š” ํ•จ์ˆ˜๊ฐ€ ๋“ค์–ด์žˆ์Œ

๐Ÿ“Œ ๋ณ€์ˆ˜๋ง๊ณ  state์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด์„œ ์“ฐ๋Š” ์ด์œ 

๋ณ€์ˆ˜๋Š” ๋ณ€๋™์‚ฌํ•ญ์ด ์ƒ๊ธฐ๋ฉด ์ž๋™์œผ๋กœ ์žฌ๋ Œ๋”๋งํ•ด์ฃผ์ง€ ์•Š์ง€๋งŒ

state๋Š” ๋ณ€๋™์‚ฌํ•ญ์ด ์ƒ๊ธฐ๋ฉด ์ž๋™์œผ๋กœ ์žฌ๋ Œ๋”๋งํ•ด์คŒ

โ‡’ ์ฆ‰ ์ž์ฃผ๋ณ€๊ฒฝ๋  ๊ฒƒ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋“ค์€ state์— ์ €์žฅํ•ด์„œ html์— ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ

์ข‹์•„์š” ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ

์ž์ฃผ ๋ฐ”๋€” ๊ฒƒ ๊ฐ™์€ html๋‚ด์šฉ์€ state๋กœ ์ €์žฅํ–ˆ๋‹ค๊ฐ€ ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์•„์š” ๊ฐœ์ˆ˜๋ฅผ state๋กœ ์‚ฌ์šฉ

onClick ์‚ฌ์šฉ๋ฒ•

1.Click๊ฐ€ ๋Œ€๋ฌธ์ž

2.{} ์ค‘๊ด„ํ˜ธ ์‚ฌ์šฉ

3.์ค‘๊ด„ํ˜ธ ์•ˆ์—๋Š” ๊ทธ๋ƒฅ ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์•ผ ์ž˜ ์ž‘๋™ํ•จ

onClick={ }์•ˆ์—๋Š” ๋งŒ๋“ค์–ด๋‘” ํ•จ์ˆ˜๋ช…์„ ์ ๊ฑฐ๋‚˜ ํ•จ์ˆ˜ํ•˜๋‚˜๋ฅผ ๋ฐ”๋กœ ๋งŒ๋“ค์–ด์„œ ์ง‘์–ด๋„ฃ์–ด์•ผํ•จ -> ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ง€๊ธฐ๋•Œ๋ฌธ์— ํ•จ์ˆ˜๋ช…์„ ์ ๋Š”๊ฒŒ ์ข‹์Œ

state๋ณ€๊ฒฝํ•˜๋Š” ๋ฒ•

๋ณ€์ˆ˜์— +1ํ• ๋ ค๋ฉด ๋ณ€์ˆ˜ += 1 ํ•˜๋ฉด ๋˜์ง€๋งŒ ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹Œ state์ด๊ธฐ ๋•Œ๋ฌธ์— state๋ณ€๊ฒฝํ•จ์ˆ˜๋ฅผ ์จ์•ผํ•จ(state์„ ์–ธ์‹œ ๋‘๋ฒˆ์งธ ์ž‘๋ช…ํ•œ ๊ฒƒ-set)

function App() {
	let [good, setGood] = useState(0);

  return (
	      <div className='list'>
        <h4>{ title[0] } <span onClick={ () => { setGood(good+1) }}>์ข‹์•„์š”๐Ÿ‘</span> { good } </h4>
        <p>today : 2022.11.10</p>
      </div>

๊ธ€์ œ๋ชฉ ๋ณ€๊ฒฝ

function App(){
  
  let [title, setTitle] = useState( ['๋‚จ์ž์ฝ”ํŠธ ์ถ”์ฒœ', '๊ฐ•๋‚จ ์šฐ๋™๋ง›์ง‘', 'ํŒŒ์ด์ฌ ๋…ํ•™'] );  
  
  return (
    <button onClick={ ()=>{ 
//ํ•ด๋‹น ์ฝ”๋“œ๋Š” ํ™•์žฅ์„ฑ ๋ถ€์กฑ ๊ธ€์ œ๋ชฉ[0] = '์—ฌ์ž์ฝ”ํŠธ ์ถ”์ฒœ'; ์œผ๋กœ๋„ ๊ฐ€๋Šฅ
      setTitle(['์—ฌ์ž์ฝ”ํŠธ ์ถ”์ฒœ', '๊ฐ•๋‚จ ์šฐ๋™๋ง›์ง‘', 'ํŒŒ์ด์ฌ ๋…ํ•™'])
    } }> ์ˆ˜์ •๋ฒ„ํŠผ </button>
  )
}

setTitle(โ€™์—ฌ์ž์ฝ”ํŠธ์ถ”์ฒœโ€™)์œผ๋กœ ํ•˜๋ฉด ๊ธฐ์กด state๋ฅผ ๊ด„ํ˜ธ์•ˆ์˜ ๋‚ด์šฉ์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ๋จ

๐Ÿ“Œ array, object ์ž๋ฃŒ๋Š” ๋ณดํ†ต ๊ธฐ์กด๊ฐ’์„ ๋ณด์กดํ•ด์ฃผ๋Š”์‹์œผ๋กœ ์ฝ”๋”ฉํ•จ

function App(){
  
  let [title, setTitle] = useState( ['๋‚จ์ž์ฝ”ํŠธ ์ถ”์ฒœ', '๊ฐ•๋‚จ ์šฐ๋™๋ง›์ง‘', 'ํŒŒ์ด์ฌ ๋…ํ•™'] );  
  
  return (
    <button onClick={ ()=>{ 
      let copy = [...๊ธ€์ œ๋ชฉ]; //state๋™์ž‘์›๋ฆฌ๋•Œ๋ฌธ
      copy[0] = '์—ฌ์ž์ฝ”ํŠธ ์ถ”์ฒœ';
      setTitle(copy)
    } }> ์ˆ˜์ •๋ฒ„ํŠผ </button>
  )
}

state ๋ณ€๊ฒฝํ•จ์ˆ˜ ๋™์ž‘์›๋ฆฌ

state๋ณ€๊ฒฝํ•จ์ˆ˜๋Š” ๋ณ€๊ฒฝํ•˜๊ธฐ ์ „์— ๊ธฐ์กดstate === ์‹ ๊ทœstate๋ฅผ ๋จผ์ € ๊ฒ€์‚ฌํ•˜๊ณ 

๊ฐ™์œผ๋ฉด state๋ณ€๊ฒฝ์„ ํ•ด์ฃผ์ง€์•Š์Œ

array / object ๋™์ž‘์›๋ฆฌ

  1. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” array/object ์ž๋ฃŒ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๋ฉด ๋žจ์ด๋ผ๋Š” ๊ฐ€์ƒ๊ณต๊ฐ„์— ์ €์žฅ์ด๋˜๊ณ  ์„ ์–ธ๋œ ๋ณ€์ˆ˜์—๋Š” ๊ทธ ์ž๋ฃŒ์˜ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ™”์‚ดํ‘œ๋งŒ ๋‹ด๊ฒจ์žˆ์Œ
let data1 = [1,2,3];
let data2 = data1;   //๋ณต์‚ฌ๋ฌธ๋ฒ•
  1. ์œ„์˜ data1๊ณผ data2๋Š” ๊ฐ๊ฐ [1,2,3]์„ ๋ณ„๊ฐœ๋กœ ์ €์žฅํ•˜๋Š”๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ฐ™์€๊ฐ’์„ ๊ณต์œ  / data1์„ ๋ณ€๊ฒฝํ•˜๋ฉด data2๋„ ์ž๋™์œผ๋กœ ๋ณ€๊ฒฝ๋จ โ‡’ ์ €์žฅ๋œ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ธฐ๋•Œ๋ฌธ, ํฌ์ธํ„ฐ๋Š๋‚Œ?
let copy = ๊ธ€์ œ๋ชฉ;
copy[0] = '์—ฌ์ž์ฝ”ํŠธ ์ถ”์ฒœ';
๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ(copy)
//์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ธฐ์กด ๊ธ€์ œ๋ชฉ๊ณผ copy๋Š” ๊ฐ™์€ ๊ณณ์„ ๊ฐ€๋ฆฌํ‚ค๊ธฐ๋•Œ๋ฌธ์— state๋ณ€๊ฒฝ์„ ํ•ด์ฃผ์ง€์•Š์Œ

spread operator ์ 3๊ฐœ ๋ฌธ๋ฒ• โ€ฆ

spread operator๋ผ๊ณ  ํ•˜๋Š” ๋ฌธ๋ฒ•

array / object์ž๋ฃŒํ˜• ์™ผ์ชฝ์— ๋ถ™์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ด„ํ˜ธ๋ฅผ ๋ฒ—๊ฒจ๋‹ฌ๋ผ๋Š” ๋œป

โ€ฆ[1,2,3] ์€ 1,2,3์ด ๋‚จ์Œ

let data1 = [1,2,3];
let data2 = [...data1];
console.log(data1 === data2) //false๋กœ ๋‚˜์˜ด

data1์— ์žˆ๋˜ ์ž๋ฃŒ๋“ค์„ ๊ด„ํ˜ธ ๋ฒ—๊ธด๋‹ค์Œ์— ๋‹ค์‹œ array๋กœ ๋งŒ๋“ค๊ฒŒ๋˜๋ฉด ๋‹ค๋ฅธ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚ด - ์ƒˆ๋กœ์šด array๋กœ ์ธ์‹ โ†’๋…๋ฆฝ์ ์ธ array๋ณต์‚ฌ๋ณธ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Œ

๋ฆฌ์•กํŠธ์—์„œ array/object state๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ์œผ๋ฉด

๋…๋ฆฝ์ ์ธ ์นดํ”ผ๋ณธ์„ ๋งŒ๋“ค์–ด์„œ ์ˆ˜์ •ํ•˜๋Š”๊ฒŒ ์ข‹์Œ

[...๊ธฐ์กดstate]

{...๊ธฐ์กดstate}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋…๋ฆฝ์ ์ธ ์นดํ”ผ๊ฐ€ ํ•˜๋‚˜ ์ƒ์„ฑ

html ์ฝ”๋“œ ์งค ๋•Œ ์œ ์˜์ 

return() ์•ˆ์— ๋‘๊ฐœ์˜ html ํƒœ๊ทธ๋ฅผ ๋‚˜๋ž€ํžˆ ์ ์œผ๋ฉด ์•ˆ๋œ๋‹ค

retrun() ๋‚ด๋ถ€๋Š” ํ•˜๋‚˜์˜ ํƒœ๊ทธ๋กœ ์‹œ์ž‘ํ•ด์„œ ํ•˜๋‚˜์˜ ํƒœ๊ทธ๋กœ ๋๋‚˜์•ผํ•จ - ์ „์ฒด๋ฅผ ํ•˜๋‚˜์˜ div๋กœ ๋ฌถ์–ด์ฃผ๋ฉด ํ•ด๊ฒฐ

return(
  <div>
    <div></div>
    <div></div>
  </div>
) //div๋ฅผ ๋‚˜๋ž€ํžˆ ์ ๊ณ ์‹ถ์„๋•Œ ์ด๋ ‡๊ฒŒ ํ•จ ->fragment๋ฌธ๋ฒ•
//<> </>๋กœ๋„ ๊ฐ€๋Šฅ

๐Ÿ“Œ ๋ณต์žกํ•œ html์„ ํ•œ ๋‹จ์–ด๋กœ ์น˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” Component๋ฌธ๋ฒ•

์ฃผ๋กœ Componentํ™” ํ•˜๋Š” ๋ถ€๋ถ„

  • ์‚ฌ์ดํŠธ์—์„œ ๋ฐ˜๋ณตํ•ด์„œ ๋‚˜์˜ค๋Š” html๋ฉ์–ด๋ฆฌ๋“ค
  • ๋‚ด์šฉ์ด ๋งค์šฐ์ž์ฃผ ๋ณ€๊ฒฝ๋ ๊ฒƒ ๊ฐ™์€ html๋ฉ์–ด๋ฆฌ
  • ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์„๋•Œ ๊ทธ ํŽ˜์ด์ง€์˜ html ์ „์ฒด
  • ํ˜‘์—…ํ•  ๋•Œ ์›นํŽ˜์ด์ง€๋ฅผ Component๋‹จ์œ„๋กœ ๋‚˜๋ˆ ์„œ ์ž‘์—…์„ ๋ถ„๋ฐฐํ•˜๊ธฐ๋„ํ•จ
function App (){
  return (
    <div>
      (์ƒ๋žต)
      <Modal></Modal>
    </div>
  )
}

function Modal(){
  return (
    <div className="modal">
      <h4>์ œ๋ชฉ</h4>
      <p>๋‚ ์งœ</p>
      <p>์ƒ์„ธ๋‚ด์šฉ</p>
    </div>
  )
}
  1. function์„ ์ด์šฉํ•ด์„œ ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  ์ž‘๋ช…
  2. ๊ทธ ํ•จ์ˆ˜ ์•ˆ return()์— html์„ ์ž‘์„ฑ
  3. ์›ํ•˜๋Š” ๊ณณ์—์„œ <ํ•จ์ˆ˜๋ช…></ํ•จ์ˆ˜๋ช…> ์‚ฌ์šฉ == <ํ•จ์ˆ˜๋ช…/>๋„ ๊ฐ™์Œ

์ถ•์•ฝํ•œ html ๋ฉ์–ด๋ฆฌ๋ฅผ Component๋ผ๊ณ  ํ•จ

Component ๋งŒ๋“ค ๋•Œ ์ฃผ์˜์ 

  1. ์ž‘๋ช…์‹œ ์ฒซ๋ฌธ์ž๋ฅผ ์˜์–ด๋Œ€๋ฌธ์ž๋กœ ๋ณดํ†ต ์ž‘๋ช…
  2. return()์•ˆ์— htmlํƒœ๊ทธ๋“ค์ด ๋ณ‘๋ ฌ๋กœ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†์Œ
  3. function App(){} ๋‚ด๋ถ€์—์„œ ๋งŒ๋“ค๋ฉด ์•ˆ๋Œ - App()๋„ ์ปดํฌ๋„ŒํŠธ์ด๊ธฐ๋•Œ๋ฌธ
  4. arrow function์จ๋„ ๋Œ

๐Ÿ“Œ Component ๋‹จ์ 

์ผ๋‹จ HTML ๊น”๋”ํ•˜๊ฒŒ ์“ฐ๋ ค๊ณ  Component๋ฅผ ์ˆ˜๋ฐฑ๊ฐœ ๋งŒ๋“ค๋ฉด ๊ทธ๊ฒƒ ๋งŒ์œผ๋กœ๋„ ๊ด€๋ฆฌ๊ฐ€ ํž˜๋“ญ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด์„œ function Modal ์•ˆ์—์„œ ๊ธ€์ œ๋ชฉ state๋ฅผ ์“ฐ๊ณ ์‹ถ์–ด์„œ {๊ธ€์ œ๋ชฉ} ์ด๋ ‡๊ฒŒ ์“ฐ๋ฉด ์ž˜ ์•ˆ๋˜๋Š”๋ฐ

์™œ๋ƒ๋ฉด ๋‹น์—ฐํžˆ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„ 

ํ•œ function ์•ˆ์— ์žˆ๋Š” ๋ณ€์ˆ˜๋ฅผ ๋‹ค๋ฅธ function์—์„œ ๋ง˜๋Œ€๋กœ ์“ธ ์ˆ˜ ์—†์–ด์„œ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

props๋ผ๋Š” ๋ฌธ๋ฒ•์„ ์ด์šฉํ•ด state๋ฅผ <Modal>๊นŒ์ง€ ์ „ํ•ด์ค˜์•ผ ๋น„๋กœ์†Œ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋ฆฌ์•กํŠธ์—์„œ ๋™์ ์ธ UI ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

  1. html css๋กœ ๋ฏธ๋ฆฌ UI ๋””์ž์ธํ•˜๊ธฐ
  2. UI์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ state๋กœ ์ €์žฅ (์Šค์œ„์น˜๊ฐ™์€ ๋Š๋‚Œ)
  3. state์— ๋”ฐ๋ผ์„œ UI๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ์กฐ๊ฑด๋ฌธ ๋“ฑ์œผ๋กœ ์ž‘์„ฑ

JSX์—์„œ ์กฐ๊ฑด๋ฌธ ์“ฐ๋Š” ๋ฒ•

JSX์•ˆ์—์„œ๋Š” if else๋ฌธ๋ฒ•์„ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ

if๋ฌธ๋ฒ•๋Œ€์‹  ์‚ผํ•ญ์—ฐ์‚ฐ์ž๋Š” JSX์ค‘๊ด„ํ˜ธ ์•ˆ์—์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅ

์กฐ๊ฑด์‹ ? ์กฐ๊ฑด์‹ ์ฐธ์ผ ๋•Œ ์ฝ”๋“œ : ์กฐ๊ฑด์‹ ๊ฑฐ์ง“์ผ ๋•Œ ์ฝ”๋“œ

function App (){

  let [modal, setModal] = useState(false);
  return (
    <div>
      (์ƒ๋žต)
//setModal(!modal) ํ•˜๋ฉด๋ˆ„๋ฅด๋ฉด ๋ณด์ด๊ณ  ํ•œ๋ฒˆ ๋” ๋ˆ„๋ฅด๋ฉด ์•ˆ๋ณด์ด๊ฒŒ ๋Œ
      <button onClick={ ()=>{ setModal(true) } }> {๊ธ€์ œ๋ชฉ[0]} </button>
      { 
         modal == true ? <Modal></Modal> : null
      }
    </div>
  )
}

๐Ÿ“Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ map ํ•จ์ˆ˜ ์“ฐ๋Š”๋ฒ•

๋ชจ๋“  array์ž๋ฃŒ ์šฐ์ธก์— map()ํ•จ์ˆ˜๋ฅผ ๋ถ™์ผ ์ˆ˜ ์žˆ์Œ

  1. array์— ๋“ค์–ด์žˆ๋Š” ์ž๋ฃŒ๊ฐœ์ˆ˜๋งŒํผ ๊ทธ ์•ˆ์— ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋ฐ˜๋ณต์‹คํ–‰ํ•ด์คŒ
  2. ์ฝœ๋ฐฑํ•จ์ˆ˜์— ํŒŒ๋ผ๋ฏธํ„ฐ ์•„๋ฌด๊ฑฐ๋‚˜ ์ž‘๋ช…ํ•˜๋ฉด ๊ทธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” array์•ˆ์— ์žˆ๋Š” ๋ชจ๋“  ์ž๋ฃŒ๋ฅผ ํ•˜๋‚˜์”ฉ ์ถœ๋ ฅ
  3. return ์˜ค๋ฅธ์ชฝ์— ๋ญ ์ ์œผ๋ฉด array๋กœ ๋„˜๊ฒจ์คŒ
var arr = [2,3,4];
var newArray = arr.map(function(a){
  return a * 10
});
console.log(newArray) //[20, 30, 40]์ถœ๋ ฅ

JSX์•ˆ์—์„œ html์„ ๋ฐ˜๋ณต์ƒ์„ฑ - map์„ ํ™œ์šฉ

function App (){
  return (
    <div>
      (์ƒ๋žต)
      { 
        ๊ธ€์ œ๋ชฉ.map(function(a){ //(a,i)๋กœ ํ•˜๋ฉด a์—๋Š” array์˜ ์ž๋ฃŒ i๋Š” 0๋ถ€ํ„ฐ1์”ฉ์ฆ๊ฐ€ํ•˜๋Š” ์ •์ˆ˜
          return (
          <div className="list" key={i}>
//map ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋ฐ˜๋ณต์ƒ์„ฑํ•œ html์—” key={i} ์ด๋Ÿฐ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผํ•จ
            <h4>{ a }</h4>
            <p>2์›” 18์ผ ๋ฐœํ–‰</p>
          </div> )
        }) 
      }
    </div>
  )
}

map ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋ฐ˜๋ณต์ƒ์„ฑํ•œ html์—” key={i} ์ด๋Ÿฐ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผํ•จ

map๋ฐ˜๋ณต์ƒ์„ฑํ•œ html์—์„œ ๊ฐ๊ฐ ์ข‹์•„์š” ์ฆ๊ฐ€์‹œํ‚ค๊ธฐ

  1. ๊ทธ๋ƒฅ๋งŒ๋“ค๋ฉด ์ข‹์•„์š”๊ฐ€ ์ „์ฒด ์ฆ๊ฐ€ํ•จ(์ข‹์•„์š”๋ฅผ ๊ธฐ๋กํ•œ state๊ฐ€ ํ•˜๋‚˜๋ผ์„œ๊ทธ๋Ÿผ)
  2. ๊ธฐ๋กํ•  state๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ๋งŒ๋“ฌ โ†’array์ž๋ฃŒ๋ฅผ ํ™œ์šฉํ•ด๋„๋Œ
  3. ์ข‹์•„์š”๋Š” stateํ•จ์ˆ˜์ด๊ธฐ๋•Œ๋ฌธ์— state๋ณ€๊ฒฝํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๊ณ , ๊ฑฐ๊ธฐ๋‹ค๊ฐ€ array์ž๋ฃŒํ˜•์ด๋‹ˆ array์ž๋ฃŒ๋ณ€๊ฒฝ์‹œ ์ฃผ์˜์ ๋„ ์‹ ๊ฒฝ์จ์•ผํ•จ

โ‡’ array์ž๋ฃŒํ˜•์ผ ๊ฒฝ์šฐ ๊ทธ๋ƒฅ ๋ฐ”๊พธ๋ฉด ๊ฐ™์€ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ธฐ๋•Œ๋ฌธ์— ๋ณ€๊ฒฝ๋˜์ง€์•Š์•„์„œ ๋ณต์‚ฌํ•˜๊ณ  ์ˆ˜์ •

<h4> 
  { ๊ธ€์ œ๋ชฉ[i] } 
   <span onClick={()=>{ 
      let copy = [...๋”ฐ๋ด‰]; //๋ณต์‚ฌ
      copy[i] = copy[i] + 1;
      ๋”ฐ๋ด‰๋ณ€๊ฒฝ(copy)  //setGood(copy)
   }}>๐Ÿ‘</span> {๋”ฐ๋ด‰[i]} 
</h4>

์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ state๊ฐ€ ํ•„์š”ํ• ๋•Œ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ์žˆ๋Š” ๋ณ€์ˆ˜๋ฅผ ๋งˆ์Œ๋Œ€๋กœ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์—†์Œ

๋‹จ ๋ถ€๋ชจ-์ž์‹๊ด€๊ณ„์ผ๋•Œ๋Š” ๋ถ€๋ชจ์ปดํฌ๋„ŒํŠธ์˜ state๋ฅผ ์ž์‹์ปดํฌ๋„ŒํŠธ๋กœ ์ „์†ก๊ฐ€๋Šฅ
์ž์‹->๋ถ€๋ชจ : ๋ถˆ๊ฐ€๋Šฅ

function App (){
  let [๊ธ€์ œ๋ชฉ, ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ] = useState(['๋‚จ์ž์ฝ”ํŠธ ์ถ”์ฒœ', '๊ฐ•๋‚จ ์šฐ๋™๋ง›์ง‘', 'ํŒŒ์ด์ฌ๋…ํ•™']);
  return (
    <div>
      <Modal></Modal>
    </div>
  )
}

function Modal(){
  return (
    <div className="modal">
      <h4>{ ๊ธ€์ œ๋ชฉ[0] }</h4>
      <p>๋‚ ์งœ</p>
      <p>์ƒ์„ธ๋‚ด์šฉ</p>
    </div>
  )
}

props๋กœ ๋ถ€๋ชจโ†’์ž์‹ state ์ „์†ก๋ฐฉ๋ฒ•

  1. ๋ถ€๋ชจ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ž์‹์ปดํฌ๋„ŒํŠธ์— ๊ฐ€์„œ <์ž์‹์ปดํฌ๋„ŒํŠธ์ด๋ฆ„ ์‚ฌ์šฉํ• ์ด๋ฆ„={state์ด๋ฆ„}/>
  2. ์ž์‹์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“œ๋Š” function์œผ๋กœ ๊ฐ€์„œ props๋ผ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ๋“ฑ๋ก ํ›„ props.์‚ฌ์šฉํ• ์ด๋ฆ„ ์œผ๋กœ ์‚ฌ์šฉ
function App (){
  let [title, setTitle] = useState(['๋‚จ์ž์ฝ”ํŠธ ์ถ”์ฒœ', '๊ฐ•๋‚จ ์šฐ๋™๋ง›์ง‘', 'ํŒŒ์ด์ฌ๋…ํ•™']);
  return (
    <div>
      <Modal setTitle={setTitle}></Modal>
    </div>
  )
}

function Modal(props){
  return (
    <div className="modal">
      <h4>{ props.setTitle[0] }</h4>
      <p>๋‚ ์งœ</p>
      <p>์ƒ์„ธ๋‚ด์šฉ</p>
    </div>
  )
}

props๋Š” ๋ฌดํ•œํžˆ ์ „์†ก๊ฐ€๋Šฅ (์—ฌ๋Ÿฌ๊ฐœ)

state์™ธ์— ์ผ๋ฐ˜๋ณ€์ˆ˜, ํ•จ์ˆ˜, ์ผ๋ฐ˜๋ฌธ์ž(์ผ๋ฐ˜๋ฌธ์ž๋Š” ์ค‘๊ด„ํ˜ธ์—†์ด ์‚ฌ์šฉ)์ „์†ก๊ฐ€๋Šฅ

<Modal ss = {๋ณ€์ˆ˜๋ช…} or {ํ•จ์ˆ˜๋ช…} > <Modal ss = โ€œ๊ฐ•๋‚จ์šฐ๋™๋ง›์ง‘>

์ž์‹ โ†’๋ถ€๋ชจ ๋ถˆ๊ฐ€๋Šฅ / ์˜†์˜ ์ปดํฌ๋„ŒํŠธ๋กœ๋„ ๋ถˆ๊ฐ€๋Šฅ โ‡’ ๋ฌด์กฐ๊ฑด ๋ถ€๋ชจ์ž์‹๊ฐ„์—๋งŒ ๊ฐ€๋Šฅ

props๋Š” ํ•จ์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฌธ๋ฒ•์ด๋ž‘ ๊ฐ™์Œ

function Modal(props){
  return (
    <div className="modal" style={{ background : props.color }}>
      <h4>{ props.๊ธ€์ œ๋ชฉ[0] }</h4>
      <p>๋‚ ์งœ</p>
      <p>์ƒ์„ธ๋‚ด์šฉ</p>
    </div>
  )
}

์ด๋ ‡๊ฒŒ ํ•ด๋†“์œผ๋ฉด Modal์‚ฌ์šฉํ•˜๋Š” ๊ณณ์—์„œ
<Modal color={โ€™blueโ€™}> <Modal color={โ€™yellowโ€™}>

์ด๋ ‡๊ฒŒ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฐ’์„ ๋ฐ”๊ฟ”์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•จ(ํŒŒ๋ผ๋ฏธํ„ฐ์ฒ˜๋Ÿผ)

<button onClick={() => { props.setTitle(['์—ฌ์ž์ฝ”ํŠธ์ถ”์ฒœ', '๊ฐ€๋‚˜๋‹ค', '๊ณต๋ถ€ํ•˜๊ธฐ'])}}>๊ธ€์ˆ˜์ •</button>

์ด๋Ÿฐ์‹์œผ๋กœ ํ•จ์ˆ˜์ž์ฒด๋ฅผ ๋„˜๊ฒจ๋ฐ›์•„์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅ

function App(){
	let [modalTitle,setModalTitle] = useState(0);{/**๋ชจ๋‹ฌ ์ฐฝ์—์„œ์˜ title์˜ ์ธ๋ฑ์Šค๋ฅผ ์œ„ํ•œ state */}
	h4๋ฅผ ๋ˆ„๋ฅด๋ฉด setModalTitle(i)
}

function Modal(props) {
  return (
    <div className="modal" style={{background : props.color}}>
      <h4>{props.title[props.modalTitle]}</h4> {/*state๋ฅผ props๋กœ ๋„˜๊ฒจ์™€์„œ ์‚ฌ์šฉ */}
      <p>๋‚ ์งœ</p>
      <p>์ƒ์„ธ๋‚ด์šฉ</p>
      {/*ํ•จ์ˆ˜๋ฅผ ๋„˜๊ฒจ๋ฐ›์•„ ์‚ฌ์šฉ */}
      <button onClick={() => { props.setTitle(['์—ฌ์ž์ฝ”ํŠธ์ถ”์ฒœ', '๊ฐ€๋‚˜๋‹ค', '๊ณต๋ถ€ํ•˜๊ธฐ'])}}>๊ธ€์ˆ˜์ •</button>
    </div>
  );
}

โ‡’ state๋ฅผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ๋งŒ๋“ค์–ด๋„๋˜์ง€๋งŒ modalTitle์ด๋ผ๋Š” state๋Š” App์—๋„ ์“ฐ๊ณ  Modal์—๋„ ์“ฐ๊ธฐ๋•Œ๋ฌธ์— ๋‹ค์–‘ํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ ์“ฐ์ด๋Š” state๋Š” ๋ถ€๋ชจ์ปดํฌ๋„ŒํŠธ์— ๋งŒ๋“ค์–ด์•ผ ๋ถ€๋ชจโ†’์ž์‹ ์ „์†ก์ด ๊ฐ€๋Šฅํ•˜๊ธฐ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์›€

โ‡’ ์ฆ‰ state๋Š” state๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์ค‘ ์ œ์ผ ์ƒ์œ„์— ์žˆ๋Š” ๋ถ€๋ชจ์ปดํฌ๋„ŒํŠธ์— ๋งŒ๋“ค์–ด์•ผํ•จ

<input>์— ์ž…๋ ฅ ์‹œ ํŠน์ • ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด

onChange ์•„๋‹ˆ๋ฉด onInput ์ด๋ฒคํŠธํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ถ€์ฐฉํ•˜๋ฉด ๋จ(์œ ์ €๊ฐ€ ์ž…๋ ฅํ• ๋•Œ๋งˆ๋‹ค ์•ˆ์— ์žˆ๋Š” ์ฝ”๋“œ ์‹คํ–‰)

์ด๋ฒคํŠธํ•ธ๋“ค๋Ÿฌ๋Š” ์ข…๋ฅ˜๊ฐ€ ๋งŽ์œผ๋‹ˆ ํ•„์š”ํ• ๋•Œ๋งˆ๋‹ค ๊ฒ€์ƒ‰ํ•ด์„œ ์‚ฌ์šฉ

<input onChange={()=>{ ์‹คํ–‰ํ• ์ฝ”๋“œ }}/>

<input>์— ์ž…๋ ฅํ•œ ๊ฐ’ ๊ฐ€์ ธ์˜ค๋Š” ๋ฒ•

<input onChange={(e)=>{ console.log(e.target.value) }}/>

e๋ผ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  e.target.value

e.target ์ด๋Ÿฌ๋ฉด ํ˜„์žฌ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ณณ์„ ์•Œ๋ ค์ฃผ๊ณ 

e.preventDefault() ์ด๋Ÿฌ๋ฉด ์ด๋ฒคํŠธ ๊ธฐ๋ณธ ๋™์ž‘์„ ๋ง‰์•„์ฃผ๊ณ 

e.stopPropagation() ์ด๋Ÿฌ๋ฉด ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง๋„ ๋ง‰์•„์ค๋‹ˆ๋‹ค. ์ด๊ฑฐ ์“ฐ๋ฉด ์ข‹์•„์š”๋ฒ„ํŠผ ๋ˆ„๋ฅผ ๋•Œ ๋ชจ๋‹ฌ์ฐฝ๋„ ๋– ๋ฒ„๋ฆฌ๋Š” ๋ฒ„๊ทธ ํ•ด๊ฒฐ๊ฐ€๋Šฅ

์‚ฌ์šฉ์ž๊ฐ€ input์— ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ ์ €์žฅํ•˜๊ธฐ

์‚ฌ์šฉ์ž๊ฐ€ input์— ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ๋Š” state์•„๋‹ˆ๋ฉด ๋ณ€์ˆ˜์— ์ €์žฅํ•ด์„œ ์“ฐ๋Š”๊ฒŒ ์ผ๋ฐ˜์ 

function App (){

  let [inputData, setInputData] = useState('');
  return (
    <input onChange={(e)=>{ 
      setInputData(e.target.value) 
      console.log(inputData)
    }} />
  )
}

์ฐธ๊ณ ์‚ฌํ•ญ

์œ„์˜ ์ฝ”๋“œ ์‹คํ–‰์‹œ ์ฒ˜์Œ ํ•œ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์ฝ˜์†”์ฐฝ์— ์•„๋ฌด๊ฒƒ๋„ ์•ˆ๋œฌ์ƒํƒœ๋กœ ์ถœ๋ ฅ๋จ

์ด์œ ๋Š” state๋ณ€๊ฒฝํ•จ์ˆ˜์˜ ํŠน์ง•๋•Œ๋ฌธ

๐Ÿ“Œ state๋ณ€๊ฒฝํ•จ์ˆ˜๋Š” ์•ฝ๊ฐ„ ๋Šฆ๊ฒŒ ์ฒ˜๋ฆฌ๋จ (๋น„๋™๊ธฐ์  ์ฒ˜๋ฆฌ)

๊ทธ๋ฆฌ๊ณ  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ๋Šฆ๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋Š” ์ฝ”๋“œ๋“ค์€ ์ž ์‹œ ์ œ์ณ๋‘๊ณ  ๋ฐ”๋กœ ๋‹ค์Œ์ค„์„ ์‹คํ–‰ํ•ด์คŒ

์˜›๋‚  React ๋ฌธ๋ฒ• - class๋ฌธ๋ฒ•์œผ๋กœ ์ปดํฌ๋„ŒํŠธ

class Modal2 extends React.Component {
  constructor(props){ //๋ถ€๋ชจ๊ฐ€ ๋ณด๋‚ธ props
    super(props);
    this.state = { //state๋ฌธ๋ฒ• - object๋ฌธ๋ฒ•๊ณผ ๋™์ผ
      name : 'kim',
      age : 20
    }
  }

  render(){
    return (
      <div>์•ˆ๋…• { this.props.ํ”„๋กญ์Šค์ด๋ฆ„ }</div> //๋ถ€๋ชจ๊ฐ€ ๋ณด๋‚ธ props์ถœ๋ ฅ
			<button onClick={()=>{ this.setState({age : 21}) }}>๋ฒ„ํŠผ</button>    )
  } //state๋ณ€๊ฒฝํ•จ์ˆ˜

}

react์—์„œ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ์‚ฌ์šฉ

๊ตฌ๊ธ€์—์„œ react bootstrap ๊ฒ€์ƒ‰ํ•˜๋ฉด ๋‚˜์˜ค๋Š” ์‚ฌ์ดํŠธ์—์„œ ์‚ฌ์ดํŠธ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์‹คํ–‰์ค‘์ด๋ฉด ๋„๊ณ  npm install์ ํ˜€์žˆ๋Š”๊ฑฐ ๋ณต๋ถ™ โ†’ ํŠน์ • ์Šคํƒ€์ผ์€ bootstrap cssํŒŒ์ผ์„ ํ•„์š”๋กœํ•˜๊ธฐ๋•Œ๋ฌธ์— ๋ณต๋ถ™

๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ๋“ค์€ ์ปดํฌ๋„ŒํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ๋“ค์€ ์ „๋ถ€ import ํ•ด์ค˜์•ผํ•จ

import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { Navbar, Container, Nav} from 'react-bootstrap';

function App() {
  return (
    <div className="App">
      
      <Navbar bg="dark" variant="dark">
        <Container>
          <Navbar.Brand href="#home">Navbar</Navbar.Brand>
          <Nav className="me-auto">
            <Nav.Link href="#home">Home</Nav.Link>
            <Nav.Link href="#features">Features</Nav.Link>
            <Nav.Link href="#pricing">Pricing</Nav.Link>
          </Nav>
        </Container>
      </Navbar>
    </div>
  );
}

export default App;

์ด๋ฏธ์ง€ ๋„ฃ๋Š” ๋ฒ•

cssํŒŒ์ผ์—์„œ srcํด๋”์•ˆ์— ์žˆ๋Š” ์‚ฌ์ง„์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด /์ด๋ฏธ์ง€๊ฒฝ๋กœ ์‚ฌ์šฉ

background-image : url('./bg.png');

html์•ˆ์—์„œ srcํด๋”์˜ ์ด๋ฏธ์ง€๋ฅผ ๋„ฃ์„๋ ค๋ฉด ์ด๋ฏธ์ง€๋ฅผ importํ•ด์˜ค๊ณ  ์‚ฌ์šฉ

  1. import ์ž‘๋ช… from './์ด๋ฏธ์ง€๊ฒฝ๋กœ' ํ•œ ๋‹ค์Œ์—
  2. ์ด๋ฏธ์ง€๊ฒฝ๋กœ๊ฐ€ ํ•„์š”ํ•œ ๊ณณ์—์„œ ์ž‘๋ช…ํ•œ๊ฑธ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

<img>ํƒœ๊ทธ ์“ฐ๊ณ ์‹ถ์œผ๋ฉด <img src={bg}/>์ด๋ ‡๊ฒŒ ์จ๋„ ๋ณด์ž…๋‹ˆ๋‹ค.

๊ท€์ฐฎ์œผ๋ฉด cssํŒŒ์ผ์„ ํ™œ์šฉํ•ฉ์‹œ๋‹ค.

import bg from './bg.png'

function App(){
  return (
    <div>
      <div className="main-bg" style={{ backgroundImage : 'url(' + bg + ')' }}></div>
    </div>
  )
}

์–ด๋”˜๊ฐ€์— ํ˜ธ์ŠคํŒ…๋˜์–ด์žˆ๋Š” ์™ธ๋ถ€ ์ด๋ฏธ์ง€๋Š” ์ ˆ๋Œ€๊ฒฝ๋กœ ๊ทธ๋Œ€๋กœ ์ž‘์„ฑํ•˜๋ฉด ์ž˜๋ณด์ž„

<img src="https://codingapple1.github.io/shop/shoes1.jpg" width="80%"></img>

๐Ÿ“Œํ™”๋ฉด์„ ๊ฐ€๋กœ๋กœ 3๋“ฑ๋ถ„

์‹ค์€ React-bootstrap ์‚ฌ์ดํŠธ์—์„œ Row ์•„๋‹ˆ๋ฉด Grid ๋ผ๊ณ  ๊ฒ€์ƒ‰

public ํด๋”์˜ ์šฉ๋„

์—ฌ๋Ÿฌ๊ฐ€์ง€ ์†Œ์Šค์ฝ”๋“œ๋Š” srcํด๋”์— ๋ณด๊ด€ / ์ด๋ฏธ์ง€๊ฐ™์€ staticํŒŒ์ผ์˜ ๊ฒฝ์šฐ publicํด๋”์— ๋ณด๊ด€ํ•ด๋„๋จ

๋ฆฌ์•กํŠธ๋กœ ๊ฐœ๋ฐœ์„ ์™„๋ฃŒํ•˜๋ฉด build์ž‘์—…์„ ํ•˜๋Š”๋ฐ ์ง€๊ธˆ๊นŒ์ง€ ์งฐ๋˜ ์ฝ”๋“œ๋ฅผ ํ•œ ํŒŒ์ผ๋กœ ์••์ถ•ํ•˜๋Š” ์ž‘์—…

srcํด๋”์— ์žˆ๋˜ ์ฝ”๋“œ์™€ ํŒŒ์ผ์€ ๋‹ค ์••์ถ•์ด ๋˜๋Š”๋ฐ publicํด๋”์— ์žˆ๋Š” ๊ฒƒ๋“ค์€ ๊ทธ๋Œ€๋กœ ๋ณด์กดํ•ด์คŒ

ํ˜•ํƒœ๋ฅผ ๋ณด์กดํ•˜๊ณ ์‹ถ์€ ์ด๋ฏธ์ง€,txt,json๋“ฑ ์ˆ˜์ •์ด ํ•„์š”์—†๋Š” staticํŒŒ์ผ๋“ค์˜ ๊ฒฝ์šฐ์—” publicํด๋”์— ๋ณด๊ด€ํ•ด๋„ ์ƒ๊ด€์—†์Œ

publicํด๋”์— ์žˆ๋Š” ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ• ๋•Œ

<img src="/logo192.png" />

๊ทธ๋ƒฅ /์ด๋ฏธ์ง€๊ฒฝ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋จ โ‡’ publicํด๋”์— ์žˆ๋Š” ์ด๋ฏธ์ง€ ์‚ฌ์šฉํ• ๋•Œ๋Š” import๋ฅผ ์•ˆํ•ด๋„๋จ , cssํŒŒ์ผ์—์„œ๋„ /์ด๋ฏธ์ง€๊ฒฝ๋กœ ์‚ฌ์šฉํ•˜๋ฉด๋จ

๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ์‹

<img src={process.env.PUBLIC_URL + '/logo192.png'} />

๋ฆฌ์•กํŠธ๋กœ ๋งŒ๋“  htmlํŽ˜์ด์ง€๋ฅผ ๋ฐฐํฌํ•  ๋•Œ codingapple.com๊ฒฝ๋กœ์— ๋ฐฐํฌํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ์—†์ง€๋งŒ

condingapple.com/์–ด์ฉŒ๊ตฌ/ ๊ฒฝ๋กœ์— ๋ฐฐํฌํ•˜๋ฉด

/logo192.png ์ด๋ ‡๊ฒŒ ์“ฐ๋ฉด ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๊ณ  ๋‚˜์˜ฌ ์ˆ˜๋„ ์žˆ์Œ

๊ทธ๋ž˜์„œ /์–ด์ฉŒ๊ตฌ/ ๋ฅผ ๋œปํ•˜๋Š” process.env.PUBLIC_URL ์ด๊ฒƒ๋„ ๋”ํ•ด์ฃผ๋ฉด ๋จ

codingapple.com/์–ด์ฉŒ๊ตฌ/ ๊ฒฝ๋กœ์— ๋ฆฌ์•กํŠธ๋กœ ๋งŒ๋“  ํŽ˜์ด์ง€๋ฅผ ๋ฐฐํฌํ•  ์ผ์ด ์•„์˜ˆ ์—†์œผ๋ฉด ๊ตณ์ด ์•ˆํ•ด๋„ ๋จ

์„œ๋ฒ„๊ฐ€ ์—†์–ด์„œ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์ง€ ๋ชปํ•˜๋‹ˆ jsํŒŒ์ผ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด์„œ ๋ฐ›์•„์˜ค๋Š”๊ฒƒ์ฒ˜๋Ÿผ ๋งŒ๋“ค๊ธฐ

export default / import ๋ฌธ๋ฒ•

์˜ˆ๋ฅผ๋“ค์–ด ์ƒํ’ˆ์ •๋ณด๋“ค์„ state๋กœ ๋งŒ๋“ค๊ณ ์‹ถ์€๋ฐ useState()์•ˆ์— ๋„ฃ๊ธฐ์—” ๋„ˆ๋ฌด ๊ธธ๋•Œ

๋‹ค๋ฅธํŒŒ์ผ์— ๋ณด๊ด€ํ–ˆ๋‹ค๊ฐ€ importํ•ด์˜ฌ ์ˆ˜ ์žˆ์Œ

(์œ ์˜์ )

  • ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ์ž๋ฃŒํ˜• ์ „๋ถ€ export ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ํŒŒ์ผ๋งˆ๋‹ค export default ๋ผ๋Š” ํ‚ค์›Œ๋“œ๋Š” ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ํŒŒ์ผ๊ฒฝ๋กœ๋Š” ./ ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ๊ฒฝ๋กœ๋ผ๋Š” ๋œป์ž„
  • export { } ํ–ˆ๋˜ ๊ฒƒ๋“ค์€ import { } ์“ธ ๋•Œ ์ž์œ ์ž‘๋ช…์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. export ํ–ˆ๋˜ ๋ณ€์ˆ˜๋ช… ๊ทธ๋Œ€๋กœ ์ ์–ด์•ผํ•จ(์—ฌ๋Ÿฌ๊ฐœ๋ณด๋‚ผ๋•Œ)
(data.js ํŒŒ์ผ)

let a = 10;
export default a; //export default ๋ณ€์ˆ˜๋ช…; ์›ํ•˜๋Š” ๋ณ€์ˆ˜๋ฅผ ๋‚ด๋ณด๋ƒ„

(App.js ํŒŒ์ผ)

import a from './data.js'; //๊ฐ€์ ธ์˜ฌํŒŒ์ผ import
console.log(a)

/////////////////์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ณ€์ˆ˜๋“ค์„ ๋‚ด๋ณด๋‚ผ๋•Œ/////////////////
(data.js ํŒŒ์ผ)

var name1 = 'Kim';
var name2 = 'Park';
export { name1, name2 } //์—ฌ๋Ÿฌ๊ฐœ ๋ณด๋‚ผ๋•Œ ์‚ฌ์šฉ

(App.js ํŒŒ์ผ)

import { name1, name2 } from './data.js';
<div className="container">
        <div className="row">
          {shoes.map(function(a, i){
            return(
              <Card shoes={shoes} i={i} key={i}></Card>
            )
          })}
        </div>
      </div> 
    </div>
  );
}

function Card(props){
  return(
    <div className="col-md-4">
//์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ž…๋ ฅ์„์œ„ํ•ด {}๋ฅผ ๋ถ™์ด๊ณ  '๋ฌธ์ž'+ ๋ณ€์ˆ˜ +'๋ฌธ์ž ํ˜•ํƒœ๋กœ ๋ฌธ์ž์ค‘๊ฐ„์— ๋ณ€์ˆ˜๋„ฃ๊ธฐ๊ฐ€๋Šฅ
      <img src={'https://codingapple1.github.io/shop/shoes'+ (props.i+1) +'.jpg'} width="80%"></img>
      <h4>{props.shoes[props.i].title}</h4>
      <p>{props.shoes[props.i].price}</p>
    </div>
)
}

ํŽ˜์ด์ง€ ๋‚˜๋ˆ„๊ธฐ

์ผ๋ฐ˜ html css js์‚ฌ์ดํŠธ๋Š” ๊ทธ๋ƒฅ htmlํŒŒ์ผ ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜์ง€๋งŒ

๋ฆฌ์•กํŠธ๋Š” ํ•˜๋‚˜์˜ htmlํŒŒ์ผ๋งŒ ์‚ฌ์šฉ

โ‡’ ๋ฆฌ์•กํŠธ์—์„œ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๋ฉด ๊ทธ๋ƒฅ ๋‚ด๋ถ€์— ์žˆ๋Š” <div>๋ฅผ ๊ฐˆ์•„์น˜์›Œ์„œ ๋ณด์—ฌ์คŒ

react-router-dom์ด๋ผ๋Š” ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•ด์„œ ๊ตฌํ˜„ํ•˜๋Š”๊ฒŒ ์ผ๋ฐ˜์ 

react-router-dom ์„ค์น˜๋ฐฉ๋ฒ•

react-router-dom ํ™ˆํŽ˜์ด์ง€๊ฐ€์„œ ๋”ฐ๋ผํ•˜๋ฉด ๋จ

ํ•ด๋‹น ํŒŒ์ผ ํ„ฐ๋ฏธ๋„์—์„œ npm install react-router-dom@6 ์ž…๋ ฅ(6๋ฒ„์ „)

์„ธํŒ…๋ฐฉ๋ฒ•

index.jsํŒŒ์ผ์—์„œ <BrowserRouter> ์ด๊ฑธ๋กœ <App/>์„ ๊ฐ์‹ธ๋ฉด ๋ (import๋Š” ์ž๋™์œผ๋กœ ๋จ / ์•ˆ๋˜๋ฉด importํ•ด์•ผ)

๋ผ์šฐํ„ฐ๋กœ ํŽ˜์ด์ง€ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ•

  1. ์šฐ์„  ์ƒ๋‹จ์—์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ปดํฌ๋„ŒํŠธ๋ฅผ import ํ•ด์˜ค๊ณ 
  2. ๋งŒ๋“ค๊ณ  ๊ทธ ์•ˆ์— ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. <Route path="/url๊ฒฝ๋กœ" element={ <๋ณด์—ฌ์ค„html> } /> ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

element์•ˆ์— html์ž‘์„ฑํ• ๋•Œ ์ฝ”๋“œ๊ฐ€ ๊ธธ๋ฉด ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ํŒŒ์ผ์— ์ž‘์„ฑ ํ›„ importํ•˜์—ฌ ์‚ฌ์šฉ=>๋ณดํ†ต ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉ

import { Routes, Route, Link } from 'react-router-dom'

function App(){
  return (
    (์ƒ๋žต)
    <Routes>
			<Route path="/" element={ <div>๋ฉ”์ธํŽ˜์ด์ง€์—์„œ ๋ณด์—ฌ์ค„๊ฑฐ</div> } />
      <Route path="/detail" element={ <div>์ƒ์„ธํŽ˜์ด์ง€์ž„</div> } />
      <Route path="/about" element={ <div>์–ด๋ฐ”์›ƒํŽ˜์ด์ง€์ž„</div> } />
    </Routes>
  )
}

ํŽ˜์ด์ง€์ด๋™ ๋ฒ„ํŠผ

๋งํฌ๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์œผ๋ฉด react-router-dom์—์„œ Link ์ปดํฌ๋„ŒํŠธ import ํ•ด์˜ค๊ณ 

์›ํ•˜๋Š” ๊ณณ์—์„œ ์“ฐ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

<Link to="/">ํ™ˆ</Link>
<Link to="/detail">์ƒ์„ธํŽ˜์ด์ง€</Link>

๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ ํด๋”๊ตฌ์กฐ

๋ฆฌ์•กํŠธ๋Š” ๊ทธ๋ƒฅ html ์ด์˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์ชผ๊ทธ๋งŒํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์—ฌ๋Ÿฌ๋ถ„์ด ๋งŒ๋“ค ํŒŒ์ผ๋“ค์€ 95% ํ™•๋ฅ ๋กœ .js ํŒŒ์ผ์ด๊ธฐ ๋•Œ๋ฌธ์—

๋น„์Šทํ•œ .js ํŒŒ์ผ๋ผ๋ฆฌ ํ•œ ํด๋”์— ๋ฌถ์–ด๋†“์œผ๋ฉด ๊ทธ๋ƒฅ ๊ทธ๊ฒŒ ์ข‹์€ ํด๋”๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ ์—ญํ• ํ•˜๋Š” js ํŒŒ์ผ์€ components ํด๋”์— ๋ฌถ๊ณ 

ํŽ˜์ด์ง€ ์—ญํ• ํ•˜๋Š” js ํŒŒ์ผ์€ routes ์•„๋‹ˆ๋ฉด pages ํด๋”์— ๋ฌถ๊ณ 

์ž์ฃผ ์“ฐ๋Š” ํ•จ์ˆ˜๊ฐ€ ๋“ค์–ด์žˆ๋Š” js ํŒŒ์ผ์€ utils ํด๋”์— ๋ฌถ๊ณ 

useNavigate , Outlet

์ƒ๋‹จ์— import

import { Routes, Route, Link, useNavigate, Outlet } from 'react-router-dom'

ํŽ˜์ด์ง€ ์ด๋™๊ธฐ๋Šฅ์„ ๋งŒ๋“ค๊ณ  ์‹ถ์œผ๋ฉด useNavigate()์‚ฌ์šฉ
useNavigate vs Link
https://velog.io/@seokkitdo/React-Link-useNavigate
Link์จ๋„ ๊ฐ€๋Šฅ

function App(){
  let navigate = useNavigate()
  
  return (
    (์ƒ๋žต)
    <button onClick={()=>{ navigate('/detail') }}>์ด๋™๋ฒ„ํŠผ</button>
  )
}

useNavigate() ์“ฐ๋ฉด ๊ทธ ์ž๋ฆฌ์— ์œ ์šฉํ•œ ํ•จ์ˆ˜๊ฐ€ ๋‚จ์Œ - ํŽ˜์ด์ง€๋ฅผ ์ด๋™์‹œ์ผœ์ฃผ๋Š” ํ•จ์ˆ˜

navigate(-1) : ๋’ค๋กœ1๋ฒˆ๊ฐ€๊ธฐ navigate(2) : ์•ž์œผ๋กœ 2๋ฒˆ๊ฐ€๊ธฐ

404ํŽ˜์ด์ง€

์œ ์ €๊ฐ€ ์ด์ƒํ•œ๊ฒฝ๋กœ๋กœ ์ ‘์†ํ–ˆ์„ ๋•Œ โ€˜์—†๋Š”ํŽ˜์ด์ง€โ€™ ์ž„์„ ์•Œ๋ ค์ฃผ๊ณ ์‹ถ์„๋•Œ

<Route path="*" element={ <div>์—†๋Š”ํŽ˜์ด์ง€์ž„</div> } />

<Route path="*"> ํ•˜๋‚˜ ๋งจ ๋ฐ‘์— ๋งŒ๋“ค์–ด๋‘๋ฉด ๋ฉ๋‹ˆ๋‹ค.

*์€ ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ๋œปํ•ด์„œ ๋งŒ๋“ค์–ด๋‘” ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ ‘์†์‹œ *๊ฒฝ๋กœ๋กœ ์•ˆ๋‚ดํ•จ

์„œ๋ธŒ๊ฒฝ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” Nested routes

<Route> ์•ˆ์— <Route>๋ฅผ ๋„ฃ๋Š”๊ฒƒ์„ Nested routes

<Route path="/about" element={ <About/> } >  
  <Route path="member" element={ <div>๋ฉค๋ฒ„๋“ค</div> } /> {/* /about/member */}
  <Route path="location" element={ <div>ํšŒ์‚ฌ์œ„์น˜</div> } /> {/* /about/location */}
</Route>

function About(){
  return (
    <div>
      <h4>aboutํŽ˜์ด์ง€์ž„</h4>
      <Outlet></Outlet>
    </div>
  )
}

/about/member โ‡’ AboutํŽ˜์ด์ง€์™€ <Outlet> ์ž๋ฆฌ์— <div>๋ฉค๋ฒ„๋“ค</div> ๋ณด์—ฌ์คŒ

/about/location โ‡’ AboutํŽ˜์ด์ง€์™€ <Outlet> ์ž๋ฆฌ์— <div>ํšŒ์‚ฌ์œ„์น˜<div> ๋ณด์—ฌ์คŒ

import ํ•ด์˜จ <Outlet>์€ nested routes ์•ˆ์˜ element๋“ค์„ ์–ด๋””์— ๋ณด์—ฌ์ค„์ง€ ํ‘œ๊ธฐํ•˜๋Š” ๊ณณ

ํŽ˜์ด์ง€ url์„ ๋ฐ”๊ฟ€๋•Œ๋งˆ๋‹ค ๊ฐ๊ฐ ๋‹ค๋ฅธ ui๋ฅผ ๋ณด์—ฌ์ฃผ๋Š”๋ฐ ์ด๊ฒƒ๋„ ๋™์ ์ด ui๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜

์žฅ์  : ๋ผ์šฐํ„ฐ๋ฅผ ์“ฐ๋ฉด ๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์ด ์ด์šฉ๊ฐ€๋Šฅํ•˜๋‹ค

์ž๋ฃŒ์˜ ์ˆœ์„œ ๋ณ€๊ฒฝ ์‹œ ์ƒ์„ธํŽ˜์ด์ง€๋„ ๊ณ ์žฅ๋‚˜๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

์ƒํ’ˆ์ˆœ์„œ๋ฅผ ๊ฐ€๋‚˜๋‹ค์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๋Š” ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด

shoes์˜ state์•ˆ์˜ ์ƒํ’ˆ์ด ๊ฐ€๋‚˜๋‹ค์ˆœ์œผ๋กœ ์ •๋ ฌ๋œ๋‹ค๊ณ  ๊ฐ€์ •

๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ธฐ ์ „์—” /detail/0ํ•˜๋ฉด White and Black๊ฐ€ ๋ณด์—ฌ์ง€๋Š”๋ฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ ํ›„์—” /detail/0ํ•˜๋ฉด Grey Yordan์ด ๋ณด์—ฌ์ง

โ‡’ ์ƒ์„ธํŽ˜์ด์ง€๊ฐ€ ๋ถˆ๊ทœ์น™ํ•ด์ง

detailPage.js์—์„œ ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ ์‹œ ์ž…๋ ฅํ•œ ๊ฐ’๋ฒˆ์งธ์˜ ์ƒํ’ˆ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฑธ๋กœ ์ฝ”๋“œ๋ฅผ ์งฌ

โ‡’ ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ƒํ’ˆ์˜ id๊ฐ€ ์ž…๋ ฅํ•œ๊ฐ’์ธ ์ƒํ’ˆ์„ ๋ณด์—ฌ์ฃผ๋Š”๊ฑธ๋กœ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝ

ํ˜„์žฌ url์— ์ž…๋ ฅํ•œ ๋ฒˆํ˜ธ์™€ ๊ฐ™์€ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ง„ ์ƒํ’ˆ์„ ์ฐพ์•„์„œ ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ

.find() , .filter() ๋ฌธ๋ฒ• ์‚ฌ์šฉ

import { useParams } from 'react-router-dom';

function DetailPage(props){

  let {id} = useParams(); //typeofํ•ด๋ณด๋ฉด string์œผ๋กœ ๋‚˜์˜ด
//arrow function์—์„œ return๊ณผ ์ค‘๊ด„ํ˜ธ๋Š” ๋™์‹œ์— ์ƒ๋žต๊ฐ€๋Šฅ
	//let findItem = props.shoes.find((x) => x.id == id ) ์ด๋ ‡๊ฒŒ ์จ๋„ ๊ฐ™์Œ
  let findItem = props.shoes.find(function(x){ //find()์ฝœ๋ฐฑํ•จ์ˆ˜์ž๋ฆฌ์— ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋„ฃ์œผ๋ฉด array์˜ ์ž๋ฃŒ๋ฅผ ๋œป
    return x.id == id //array์ž๋ฃŒ.id == url์— ์ž…๋ ฅํ•œ ๋ฒˆํ˜ธ
  })

  return (
    <div className="container">
      <div className="row">
        <div className="col-md-6">
          <img src={'https://codingapple1.github.io/shop/shoes'+ (findItem.id+1) + '.jpg'} width="100%" ></img>
        </div>
        <div className="col-md-6">
          <h4 className="pt-5">{findItem.title}</h4>
          <p>{findItem.content}</p>
          <p>{findItem.price}</p>
          <button className="btn btn-danger">์ฃผ๋ฌธํ•˜๊ธฐ</button>
        </div>
      </div>
    </div>
  );
}

export default DetailPage;

styled-component

์„ค์น˜ (npm install styled-components)

์Šคํƒ€์ผ์„ ๋ฐ”๋กœ ์ž…ํ˜€์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

import styled from 'styled-components'

์žฅ์ 1.ย CSS ํŒŒ์ผ ์˜คํ”ˆํ•  ํ•„์š”์—†์ด JS ํŒŒ์ผ์—์„œ ๋ฐ”๋กœ ์Šคํƒ€์ผ๋„ฃ์„ ์ˆ˜ ์žˆ์Œ

์žฅ์ 2.ย ์—ฌ๊ธฐ ์ ์€ ์Šคํƒ€์ผ์ด ๋‹ค๋ฅธ JS ํŒŒ์ผ๋กœ ์˜ค์—ผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์›๋ž˜ ๊ทธ๋ƒฅ CSSํŒŒ์ผ์€ ์˜ค์—ผ๋ฉ๋‹ˆ๋‹ค.

์žฅ์ 3.ย ํŽ˜์ด์ง€ ๋กœ๋”ฉ์‹œ๊ฐ„ ๋‹จ์ถ•๋ฉ๋‹ˆ๋‹ค.

์™œ๋ƒ๋ฉด ์ €๊ธฐ ์ ์€ ์Šคํƒ€์ผ์€ html ํŽ˜์ด์ง€์˜ <style>ํƒœ๊ทธ์— ๋„ฃ์–ด์ค˜์„œ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜ cssํŒŒ์ผ ์˜ค์—ผ๋ฐฉ์ง€ ๋ฐฉ๋ฒ•

์—ฌ๋Ÿฌ๋ถ„์ด App.css ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ App.js์—์„œ importํ•ด์„œ ์“ด๋‹ค๊ณ  ํ•ด๋„

๊ฑฐ๊ธฐ ์ ์€ ํด๋ž˜์Šค๋ช…๋“ค์€ Detail.js๊นŒ์ง€ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. (์˜ค์—ผ๋จ)

ํ”„๋กœ์ ํŠธ ์‚ฌ์ด์ฆˆ๊ฐ€ ์ž‘์„ ๋• ํŽธ๋ฆฌํ•˜๊ฒ ์ง€๋งŒ ์‚ฌ์ด์ฆˆ๊ฐ€ ์ปค์ง€๋ฉด ๊ด€๋ฆฌํ•˜๊ธฐ ํž˜๋“ค์–ด์ง‘๋‹ˆ๋‹ค.

๊ทธ๋Ÿด ๋• styled-components ์จ๋„ ๋˜์ง€๋งŒ ๊ทธ๋ƒฅ CSSํŒŒ์ผ์—์„œ๋„ ๋‹ค๋ฅธ JS ํŒŒ์ผ์— ๊ฐ„์„ญํ•˜์ง€ ์•Š๋Š” '๋ชจ๋“ˆํ™”' ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š”๋ฐ

์ปดํฌ๋„ŒํŠธ๋ช….module.css

์ด๋ ‡๊ฒŒ CSS ํŒŒ์ผ์„ ์ž‘๋ช…ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ex) App.module.css / detailPage.module.css

๊ทธ๋ฆฌ๊ณ  ์ปดํฌ๋„ŒํŠธ๋ช….js ํŒŒ์ผ์—์„œ import ํ•ด์„œ ์“ฐ๋ฉด ๊ทธ ์Šคํƒ€์ผ๋“ค์€ ์ปดํฌ๋„ŒํŠธ๋ช….js ํŒŒ์ผ์—๋งŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

  1. ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ๋ฒ•
let Box = styled.div`
  padding : 20px;
  color : grey
`;
let YellowBtn = styled.button`
  background : yellow;
  color : black;
  padding : 10px;
`;

function Detail(){
  return (
    <div>
      <Box>
        <YellowBtn>๋ฒ„ํŠผ์ž„</YellowBtn>
      </Box>
    </div>
  )
}
  1. props๋กœ ์žฌํ™œ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ
import styled from 'styled-components';

let YellowBtn = styled.button`
  background : ${ props => props.bg }; //bg ์ž๋ฆฌ์— ์ž์œ ๋กญ๊ฒŒ ์ž‘๋ช…๊ฐ€๋Šฅ
	color : ${ props => props.bg == 'blue' ? 'white' : 'black' };
//bg๊ฐ€ blue๋ฉด ๊ธ€์ž์ƒ‰์„ white๋กœ ์•„๋‹ˆ๋ฉด black์œผ๋กœ ์‚ผํ•ญ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ
  padding : 10px;
`;

function Detail(){
  return (
    <div>
        <YellowBtn bg="orange">์˜ค๋ Œ์ง€์ƒ‰ ๋ฒ„ํŠผ์ž„</YellowBtn>
        <YellowBtn bg="blue">ํŒŒ๋ž€์ƒ‰ ๋ฒ„ํŠผ์ž„</YellowBtn>
    </div>
  )
}

๋‹จ์ 1.ย JS ํŒŒ์ผ์ด ๋งค์šฐ ๋ณต์žกํ•ด์ง

๊ทธ๋ฆฌ๊ณ  ์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ styled ์ธ์ง€ ์•„๋‹ˆ๋ฉด ์ผ๋ฐ˜ ์ปดํฌ๋„ŒํŠธ์ธ์ง€ ๊ตฌ๋ถ„๋„ ์–ด๋ ค์›Œ์ง

๋‹จ์ 2.ย JS ํŒŒ์ผ ๊ฐ„ ์ค‘๋ณต ๋””์ž์ธ์ด ๋งŽ์ด ํ•„์š”ํ•˜๋ฉด ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์Šคํƒ€์ผ ๋„ฃ์€ ๊ฒƒ๋“ค import ํ•ด์™€์„œ ์‚ฌ์šฉ

๊ทผ๋ฐ ๊ทธ๋Ÿผ CSSํŒŒ์ผ ์“ฐ๋Š”๊ฑฐ๋ž‘ ์ฐจ์ด๊ฐ€ ์—†์–ด์ง

๋‹จ์ 3.ย CSS ๋‹ด๋‹นํ•˜๋Š” ๋””์ž์ด๋„ˆ๊ฐ€ ์žˆ๋‹ค๋ฉด ํ˜‘์—…์‹œ ๋ถˆํŽธํ• ํ…๋ฐ ๊ทธ ์‚ฌ๋žŒ์ด styled-components ๋ฌธ๋ฒ•์„ ๋ชจ๋ฅธ๋‹ค๋ฉด

๊ทธ ์‚ฌ๋žŒ์ด CSS๋กœ ์ง ๊ฑธ styled-components ๋ฌธ๋ฒ•์œผ๋กœ ๋‹ค์‹œ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ๊ทธ๋Ÿฐ ์ž‘์—…์ด ํ•„์š”ํ•ด์ง

ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์ž˜์ƒ๊ฐํ•ด๋ณด๊ณ  ์‚ฌ์šฉํ•ด์•ผํ•จ

๐Ÿ“Œ ์ปดํฌ๋„ŒํŠธ์˜ Lifecycle

  1. ์ƒ์„ฑ์ด ๋  ์ˆ˜๋„ ์žˆ๊ณ  (mount)
  2. ์žฌ๋ Œ๋”๋ง์ด ๋  ์ˆ˜๋„ ์žˆ๊ณ  (update)
  3. ์‚ญ์ œ๊ฐ€ ๋  ์ˆ˜๋„ ์žˆ๋‹ค(unmount)

์ปดํฌ๋„ŒํŠธ์˜ lifecycle ์ค‘๊ฐ„์ค‘๊ฐ„์— ๊ฐ„์„ญ(์ฝ”๋“œ์‹คํ–‰)์ด ๊ฐ€๋Šฅ โ‡’ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ ๊ธฐ๋ฐœ์ด ๊ฐ€๋Šฅ

์ปดํฌ๋„ŒํŠธ Lifecycle์— ๊ฐ„์„ญ(์ฝ”๋“œ์‹คํ–‰)ํ•˜๋Š” ๋ฐฉ๋ฒ•

๊ฐˆ๊ณ ๋ฆฌ๋ฅผ ๋‹ฌ์•„์„œ ์ฝ”๋“œ๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋จ

hook(๊ฐˆ๊ณ ๋ฆฌ) ์„ ๋‹ฌ์•„์คŒ โ‡’ Lifecycle hook์ด๋ผ๊ณ  ๋ถ€๋ฆ„

์š”์ฆ˜ React์—์„œ Lifecycle hook ์“ฐ๋Š” ๋ฐฉ๋ฒ•

import {useState, useEffect} from 'react'; //useEffect importํ•ด์•ผํ•จ

function Detail(){

  useEffect(()=>{
    //์—ฌ๊ธฐ์ ์€ ์ฝ”๋“œ๋Š” ์ปดํฌ๋„ŒํŠธ ๋กœ๋“œ & ์—…๋ฐ์ดํŠธ ๋งˆ๋‹ค ์‹คํ–‰๋จ
    console.log('์•ˆ๋…•')
  });

  let [count, setCount] = useState(0)
  
  return (
    <button onClick={()=>{ setCount(count+1) }}>๋ฒ„ํŠผ</button>
  )
}

useEffect์— ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ์•ˆ์— ์ฝ”๋“œ๋ฅผ ์ ์œผ๋ฉด ํ•ด๋‹น ์ฝ”๋“œ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ mount & update ์‹œ ์‹คํ–‰๋จ

โ€˜์•ˆ๋…•โ€™์ด 2๋ฒˆ ์ถœ๋ ฅ

โ‡’ index.js์— <React.StrictMode>๋ผ๋Š” ํƒœ๊ทธ๊ฐ€ ์žˆ์œผ๋ฉด 2๋ฒˆ ์ถœ๋ ฅํ•ด์คŒ

๋””๋ฒ„๊น…์šฉ์œผ๋กœ ํŽธํ•˜๋ผ๊ณ  2๋ฒˆ ์ถœ๋ ฅํ•ด์ฃผ๋Š”๋ฐ ์‹ซ์œผ๋ฉด ์ € ํƒœ๊ทธ๋ฅผ ์ œ๊ฑฐ

useEffect๋ฐ–์— ์ ์–ด๋„ ๋˜‘๊ฐ™์ด ๋™์ž‘?

useEffect ๋ฐ–์— ์ ์–ด๋„ ๋˜‘๊ฐ™์ด ์ปดํฌ๋„ŒํŠธ mount & update ์‹œ ์‹คํ–‰๋จ

-์ปดํฌ๋„ŒํŠธ๊ฐ€ mount & update ์‹œ function ์•ˆ์— ์žˆ๋Š” ์ฝ”๋“œ๋„ ๋‹ค์‹œ ์ฝ๊ณ  ์ง€๋‚˜๊ฐ€๊ธฐ ๋•Œ๋ฌธ

โ‡’useEffect ์•ˆ์— ์ ์€ ์ฝ”๋“œ๋Š” html ๋žœ๋”๋ง ์ดํ›„์— ๋™์ž‘ํ•จ

์˜ˆ๋ฅผ ๋“ค์–ด ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ฆฌ๋Š” ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ๊ฐ€์ •

function Detail(){

  (๋ฐ˜๋ณต๋ฌธ 10์–ต๋ฒˆ ๋Œ๋ฆฌ๋Š” ์ฝ”๋“œ)
  return (์ƒ๋žต)
}

-์—ฌ๊ธฐ์— html์ ์œผ๋ฉด ๋ฐ˜๋ณต๋ฌธ๋Œ๋ฆฌ๊ณ  ๋‚˜์„œ html์„ ๋ณด์—ฌ์คŒ

function Detail(){

  useEffect(()=>{
    (๋ฐ˜๋ณต๋ฌธ 10์–ต๋ฒˆ ๋Œ๋ฆฌ๋Š” ์ฝ”๋“œ)
  });
  
  return (์ƒ๋žต)
}

-useEffect์•ˆ์— ์ ์œผ๋ฉด html ๋ณด์—ฌ์ฃผ๊ณ ๋‚˜์„œ ๋ฐ˜๋ณต๋ฌธ ์‹คํ–‰

โ‡’useEffect๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ์‹คํ–‰์‹œ์ ์„ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ์Œ

ํ•จ์ˆ˜๋ฅผ useEffect๋ผ๊ณ  ์ž‘๋ช…ํ•œ ์ด์œ  - ํ•จ์ˆ˜์˜ ํ•ต์‹ฌ๊ธฐ๋Šฅ ์™ธ์— ์“ธ๋ฐ์—†๋Š” ๊ธฐ๋Šฅ๋“ค์„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์šฉ์–ด๋กœ side effect

์ปดํฌ๋„ŒํŠธ์˜ ํ•ต์‹ฌ๊ธฐ๋Šฅ์€ html ๋ Œ๋”๋ง์ด๋ผ side effect์—์„œ ์ด๋ฆ„์„ ๋”ฐ์˜ด

html ๋ Œ๋”๋ง ์™ธ์˜ ์“ธ๋ฐ์—†๋Š” ๊ธฐ๋Šฅ๋“ค์€ useEffect์•ˆ์— ์ ๊ธฐ

์˜ค๋ž˜๊ฑธ๋ฆฌ๋Š” ๋ฐ˜๋ณต์—ฐ์‚ฐ, ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€์ ธ์˜ค๋Š” ์ž‘์—… , ํƒ€์ด๋จธ๋‹ค๋Š”๊ฒƒ๋“ค์„ useEffect ์•ˆ์— ๋งŽ์ด ์ ์Œ

๐Ÿ“Œ ๋ฆฌ์•กํŠธ์—์„œ ๋™์ ์ธ UI ๋งŒ๋“ค๊ธฐ

  1. UI ์ƒํƒœ๋ฅผ ์ €์žฅํ•  state ๋งŒ๋“ค๊ณ 
  2. state์— ๋”ฐ๋ผ์„œ UI๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ์ž‘์„ฑ
function Detail(){

  let [alert, setAlert] = useState(true) //UI์ƒํƒœ๋ฅผ ์ €์žฅํ•  state
  useEffect(()=>{
    setTimeout(()=>{ setAlert(false) }, 2000) //2์ดˆ ํ›„ alert๋ฅผ false
  }, []) //[]๋Š” ์‹คํ–‰์กฐ๊ฑด - ์•„๋ฌด๊ฒƒ๋„ ์•ˆ๋“ค์–ด๊ฐ€์žˆ๊ธฐ ๋•Œ๋ฌธ์— mount์‹œ 1ํšŒ๋งŒ ์‹คํ–‰

  return (
  {
//์‚ผํ•ญ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ
    alert == true
    ? <div className="alert alert-warning">
        2์ดˆ์ด๋‚ด ๊ตฌ๋งค์‹œ ํ• ์ธ
      </div>
    : null
  }
  )
}

useEffect์— ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ์‹คํ–‰์กฐ๊ฑด

useEffect(()=>{ ์‹คํ–‰ํ• ์ฝ”๋“œ }, [count]) //count๊ฐ€ ๋ณ€ํ• ๋•Œ๋งŒ ์ฝ”๋“œ ์‹คํ–‰
useEffect(()=>{ ์‹คํ–‰ํ• ์ฝ”๋“œ }, [])

useEffect์˜ ๋‘๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ []๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š”๋ฐ ์—ฌ๊ธฐ์— ๋ณ€์ˆ˜๋‚˜ state๊ฐ™์€ ๊ฒƒ๋“ค์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์Œ(์—ฌ๋Ÿฌ๊ฐœ ๊ฐ€๋Šฅ)

โ†’ []์•ˆ์— ๋„ฃ์œผ๋ฉด []์— ์žˆ๋Š” ๋ณ€์ˆ˜๋‚˜ state๊ฐ€ ๋ณ€ํ• ๋•Œ๋งŒ useEffect์•ˆ์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰

[]์•ˆ์— ์•„๋ฌด๊ฒƒ๋„ ์•ˆ๋„ฃ์œผ๋ฉด ์ปดํฌ๋„ŒํŠธ mount์‹œ(๋กœ๋“œ์‹œ) 1ํšŒ๋งŒ ์‹คํ–‰ํ•˜๊ณ  ๋”์ด์ƒ ์‹คํ–‰ํ•˜์ง€์•Š์Œ

clean up function

useEffect๋™์ž‘ํ•˜๊ธฐ ์ „์— ํŠน์ •์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์œผ๋ฉด return ()โ‡’{}์•ˆ์— ๋„ฃ์œผ๋ฉด ๋จ

return ์•ˆ์— ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์‹คํ–‰

useEffect(()=>{ 
  ๊ทธ ๋‹ค์Œ ์‹คํ–‰๋จ 
  return ()=>{
    ์—ฌ๊ธฐ์žˆ๋Š”๊ฒŒ ๋จผ์ €์‹คํ–‰๋จ
  }
}, [count])

์˜ˆ๋ฅผ ๋“ค๋ฉด ์ˆ™์ œ๋กœ ํ–ˆ๋˜ setTimeout ํƒ€์ด๋จธ์ธ๋ฐ

setTimeout() ์“ธ ๋•Œ๋งˆ๋‹ค ๋ธŒ๋ผ์šฐ์ € ์•ˆ์— ํƒ€์ด๋จธ๊ฐ€ ํ•˜๋‚˜ ์ƒ๊น€

๊ทผ๋ฐ useEffect ์•ˆ์— ์ผ๊ธฐ ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ๊ฐ€ mount ๋  ๋•Œ ๋งˆ๋‹ค ์‹คํ–‰

๊ทธ๋Ÿผ ์ž˜๋ชป ์ฝ”๋“œ๋ฅผ ์งœ๋ฉด ํƒ€์ด๋จธ๊ฐ€ 100๊ฐœ 1000๊ฐœ ์ƒ๊ธธ ์ˆ˜๋„ ์žˆ์Œ

๋‚˜์ค‘์— ๊ทธ๋Ÿฐ ๋ฒ„๊ทธ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ์‹ถ์œผ๋ฉดuseEffect์—์„œ ํƒ€์ด๋จธ ๋งŒ๋“ค๊ธฐ ์ „์— ๊ธฐ์กด ํƒ€์ด๋จธ๋ฅผ ์‹น ์ œ๊ฑฐํ•˜๋ผ๊ณ  ์ฝ”๋“œ๋ฅผ ์งœ๋ฉด ๋˜๋Š”๋ฐ

๊ทธ๋Ÿฐ๊ฑฐ ์งค ๋•Œ return ()=>{} ์•ˆ์— ์งœ๋ฉด ๋จ

useEffect(()=>{ 
  let a = setTimeout(()=>{ setAlert(false) }, 2000) //์ œ๊ฑฐํ•˜๊ธฐ์œ„ํ•ด์„œ ๋ณ€์ˆ˜์— ๋„ฃ๊ณ 
  return ()=>{
    clearTimeout(a) //ํƒ€์ด๋จธ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ํ•จ์ˆ˜
  }
}, [])
  • clean up function์—๋Š” ํƒ€์ด๋จธ์ œ๊ฑฐ, socket ์—ฐ๊ฒฐ์š”์ฒญ์ œ๊ฑฐ, ajax์š”์ฒ˜ ์ค‘๋‹จ ๋“ฑ ์ด๋Ÿฐ ์ฝ”๋“œ๋ฅผ ๋งŽ์ด ์ž‘์„ฑ
  • ์ปดํฌ๋„ŒํŠธ unmount ์‹œ์—๋„ clean up function ์•ˆ์— ์žˆ๋Š”๊ฒŒ 1ํšŒ ์‹คํ–‰

๐Ÿ“Œ ์ •๋ฆฌ

useEffect( ()=>{ ์‹คํ–‰ํ• ์ฝ”๋“œ } ) // ์žฌ๋žœ๋”๋ง๋งˆ๋‹ค ์ฝ”๋“œ ์‹คํ–‰๊ฐ€๋Šฅ
useEffect( ()=>{ ์‹คํ–‰ํ• ์ฝ”๋“œ }, [] ) //์ปดํฌ๋„ŒํŠธ mount์‹œ 1ํšŒ๋งŒ ์‹คํ–‰
useEffect( ()=>{ return ()=>{ ์‹คํ–‰ํ• ์ฝ”๋“œ } } ) //useEffect์•ˆ์˜ ์ฝ”๋“œ์‹คํ–‰์ „์— ํ•ญ์ƒ ์‹คํ–‰
useEffect( ()=>{ return ()=>{ ์‹คํ–‰ํ• ์ฝ”๋“œ } }, [] ) //์ปดํฌ๋„ŒํŠธ unmount์‹œ 1ํšŒ ์‹คํ–‰
useEffect( ()=>{ ์‹คํ–‰ํ• ์ฝ”๋“œ }, [state1] ) //state1์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ ์‹คํ–‰

input์— ์ˆซ์ž๋ง๊ณ  ๋‹ค๋ฅธ๊ฑธ ์ž…๋ ฅํ•˜๋ฉด alert์ฐฝ๋„์šฐ๊ธฐ

input์— ์ž…๋ ฅํ•œ ๊ฐ’์„ ์ „๋ถ€ ๋ฌธ์žํ˜•ํƒœ๋กœ ์ถœ๋ ฅ โ†’ โ€˜123โ€™ โ€˜ใ„ฑใ„ดใ„ทโ€™์ด๋ ‡๊ฒŒ ์ˆซ์ž๊ฐ€ ์—†๋Š” ๋ฌธ์ž์ธ์ง€ ํŒŒ์•…ํ•˜๊ณ  ์‹ถ์œผ๋ฉด isNaN()์‚ฌ์šฉ

function Detail(){
  let [num, setNum] = useState('')

  useEffect(()=>{
    if (isNaN(num) == true){ //๋ฌธ์ž๊ฐ€ ๋“ค์–ด์žˆ์œผ๋ฉด true๊ฐ€ ๋‚˜์˜ด
      alert('๊ทธ๋Ÿฌ์ง€๋งˆ์„ธ์š”')
    }
  }, [num])

  return (
    <input onChange((e)=>{ setNum(e.target.value) }) />
  )
}

์„œ๋ฒ„ ์š”์ฒญ

  1. ์–ด๋–ค ๋ฐ์ดํ„ฐ์ธ์ง€ (URL ํ˜•์‹์œผ๋กœ)
  2. ์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ ์š”์ฒญํ• ์ง€(GET or POST)

๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ (GET) / ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ ๋ณด๋‚ผ ๋•Œ (POST)

GET / POST ์š”์ฒญํ•˜๋Š” ๋ฒ•

POST์š”์ฒญ์„ ๋‚ ๋ฆฌ๊ณ  ์‹ถ์œผ๋ฉด

<form action="์š”์ฒญํ• url" method="post">

โ†’ GET, POST ์š”์ฒญ์„ ์ €๋ ‡๊ฒŒ ๋‚ ๋ฆฌ๋ฉด ๋‹จ์  : ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ๋จ

AJAX๋ž€?

์„œ๋ฒ„์— GET, POST์š”์ฒญํ•  ๋•Œ ์ƒˆ๋กœ๊ณ ์นจ ์—†์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๊ฐ„๋‹จํ•œ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋Šฅ

AJAX๋กœ GET/POST์š”์ฒญํ•˜๋Š” ๋ฐฉ๋ฒ• 3๊ฐœ

  1. XMLHttpRequest๋ผ๋Š” ์˜›๋‚  ๋ฌธ๋ฒ• ์“ฐ๊ธฐ
  2. fetch()๋ผ๋Š” ์ตœ์‹  ๋ฌธ๋ฒ• ์“ฐ๊ธฐ
  3. axios๊ฐ™์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์“ฐ๊ธฐ โ†’ ์ด๊ฒŒ ๊ฐ€์žฅ ํŽธํ•จ

โ‡’ npm install axios๋กœ ์„ค์น˜

AJAX ์š”์ฒญํ•˜๋Š” ๋ฐฉ๋ฒ•

  1. ์ƒ๋‹จ์— axios๋ฅผ importํ•จ
  2. axios.get(URL) ์ด๋Ÿฌ๋ฉด ํ•ด๋‹น url๋กœ get์š”์ฒญ์ด ๋จ
  3. ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜จ ๊ฒฐ๊ณผ๋Š” ๊ฒฐ๊ณผ.data์•ˆ์— ๋“ค์–ด์žˆ์Œ
  4. ์ธํ„ฐ๋„ท์ด ์•ˆ๋˜๊ฑฐ๋‚˜ url์ด ์ด์ƒํ•˜๋ฉด ์‹คํŒจํ•˜๋Š”๋ฐ ์‹คํŒจํ–ˆ์„ ๋•Œ ์‹คํ–‰ํ•  ์ฝ”๋“œ๋Š” .catch()์•ˆ์— ์ ์œผ๋ฉด ๋จ
import axios from 'axios'

function App(){
  return (
    <button onClick={()=>{
        axios.get('https://codingapple1.github.io/shop/data2.json')
        .then((result)=>{
          //console.log(result.data) ์—ฌ๊ธฐ์—์„œ ๊ฒฐ๊ณผ๊ฐ€ ๋“ค์–ด์žˆ์Œ
          let newShoes = shoes.concat(result.data)
					// let copy = [...shoes, ...result.data] ์ด๋ ‡๊ฒŒ๋„ ๊ฐ€๋Šฅ
          // console.log(copy)
          setShoes(newShoes)
        })
        .catch(()=>{
          console.log('์‹คํŒจ')
        })
      }}>์ƒํ’ˆ ๋”๋ณด๊ธฐ</button>
  )
}

POST ์š”์ฒญํ•˜๋Š”๋ฒ•

axios.post('URL', {name : 'kim'})
//url์„œ๋ฒ„๋กœ ์ž๋ฃŒ์ „์†ก / ์™„๋ฃŒ์‹œ ํŠน์ •์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์œผ๋ฉด .then()์„ ๋ถ™์ด๋ฉด๋จ

๋™์‹œ์— AJAX์š”์ฒญ ์—ฌ๋Ÿฌ๊ฐœ ๋‚ ๋ฆฌ๊ธฐ

Promise.all( [axios.get('URL1'), axios.get('URL2')] )

url1 ,url2๋กœ get์š”์ฒญ์„ ๋™์‹œ์— ํ•ด์คŒ

๋‘˜๋‹ค ์™„๋ฃŒ ์‹œ ํŠน์ • ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์œผ๋ฉด .then()๋’ค์— ๋ถ™์ด๋ฉด ๋จ

๐Ÿ“Œ ์›๋ž˜ ์„œ๋ฒ„์™€ ๋ฌธ์ž์ž๋ฃŒ๋งŒ ์ฃผ๊ณ ๋ฐ›๊ธฐ ๊ฐ€๋Šฅ

array / object ์ฃผ๊ณ ๋ฐ›๊ธฐ ๋ถˆ๊ฐ€๋Šฅ โ†’ ์ž๋ฃŒ์— ๋”ฐ์˜ดํ‘œ๋ฅผ ์น˜๋ฉด ๊ฐ€๋Šฅ

"{"name" : "kim"}"

์ด๊ฑธ JSON ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

JSON์€ ๋ฌธ์ž ์ทจ๊ธ‰์„ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„์™€ ์ž์œ ๋กญ๊ฒŒ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์‹ค์ œ๋กœ ๊ฒฐ๊ณผ.data ์ถœ๋ ฅํ•ด๋ณด๋ฉด ๋”ฐ์˜ดํ‘œ์ณ์ง„ JSON์ด ๋‚˜์™€์•ผํ•˜๋Š”๋ฐ

axios ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” JSON -> object/array ๋ณ€ํ™˜์ž‘์—…์„ ์ž๋™์œผ๋กœ ํ•ด์ค˜์„œ

์ถœ๋ ฅํ•ด๋ณด๋ฉด object/array๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

fetch('URL').then(๊ฒฐ๊ณผ => ๊ฒฐ๊ณผ.json()).then((๊ฒฐ๊ณผ) => { console.log(๊ฒฐ๊ณผ) } )

์ƒ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ๋ฒ•์ธ fetch()๋ฅผ ์ด์šฉํ•ด์„œ get/post ์š”์ฒญ์ด ๊ฐ€๋Šฅํ•œ๋ฐ

์ด๊ฑด JSON โ†’ object/array ๋กœ ์ž๋™์œผ๋กœ ์•ˆ๋ฐ”๊ฟ”์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ง์ ‘ ๋ฐ”๊พธ๋Š” ์ž‘์—…์ด ํ•„์š”

AJAX๋กœ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ html์— ๊ฝ‚์„ ๋•Œ ์—๋Ÿฌ๋‚˜๋Š” ์ด์œ 

  1. ajax์š”์ฒญ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์„œ
  2. state์— ์ €์žฅํ•˜๋ผ๊ณ  ์ฝ”๋“œ๋ฅด ์งœ๋†“๊ณ 
  3. state๋ฅผ html์— ๋„ฃ์–ด์„œ ๋ณด์—ฌ๋‹ฌ๋ผ๊ณ 
    <div> {state.ใ…‡ใ…‡}</div>

์ด๋•Œ state๊ฐ€ ๋น„์–ด์žˆ๋‹ค๊ณ  ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ

์ด์œ ๋Š” ajax์š”์ฒญ๋ณด๋‹ค html๋ Œ๋”๋ง์ด ๋” ๋นจ๋ผ์„œ ๊ทธ๋Ÿด ์ˆ˜ ์žˆ์Œ

state์•ˆ์— ๋ญ๊ฐ€ ๋“ค์–ด์žˆ์œผ๋ฉด ๋ณด์—ฌ๋‹ฌ๋ผ๊ณ  if๋ฌธ ๊ฐ™์€๊ฑธ ์ถ”๊ฐ€ํ•˜๋ฉด ๋จ

tab๋งŒ๋“ค๊ธฐ

function Detail(){
  let [ํƒญ, ํƒญ๋ณ€๊ฒฝ] = useState(0)
  
  return (
		<Nav variant="tabs"  defaultActiveKey="link0">
	    <Nav.Item>
	      <Nav.Link onClick={()=>{ ํƒญ๋ณ€๊ฒฝ(0) }} eventKey="link0">๋ฒ„ํŠผ0</Nav.Link>
	    </Nav.Item>
	    <Nav.Item>
	      <Nav.Link onClick={()=>{ ํƒญ๋ณ€๊ฒฝ(1) }} eventKey="link1">๋ฒ„ํŠผ1</Nav.Link>
	    </Nav.Item>
	    <Nav.Item>
	      <Nav.Link onClick={()=>{ ํƒญ๋ณ€๊ฒฝ(2) }} eventKey="link2">๋ฒ„ํŠผ2</Nav.Link>
	    </Nav.Item>
		</Nav>
    <TabContent ํƒญ={ํƒญ}/>
  )
}

function TabContent(props){
  if (props.ํƒญ === 0){
    return <div>๋‚ด์šฉ0</div>
  }
  else if (props.ํƒญ === 1){
    return <div>๋‚ด์šฉ1</div>
  }
  else if (props.ํƒญ === 2){
    return <div>๋‚ด์šฉ2</div>
  }
}

๋‹ค๋ฅธ๋ฐฉ๋ฒ•

function TabContent(props){
  return [ <div>๋‚ด์šฉ0</div>, <div>๋‚ด์šฉ1</div>, <div>๋‚ด์šฉ2</div> ][props.ํƒญ]
} //props.ํƒญ์ด 0์ด๋ฉด array์ž๋ฃŒ์—์„œ 0๋ฒˆ์ž๋ฃŒ๋ฅผ ๊บผ๋‚ด์คŒ

props ์‰ฝ๊ฒŒ ์“ฐ๋Š” ๋ฐฉ๋ฒ•

function TabContent({ํƒญ}){
  return [ <div>๋‚ด์šฉ0</div>, <div>๋‚ด์šฉ1</div>, <div>๋‚ด์šฉ2</div> ][ํƒญ]
}

์ž์‹์ปดํฌ๋„ŒํŠธ์—์„œ props๋ผ๊ณ  ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ•˜๋‚˜๋งŒ ์ž‘๋ช…ํ•˜๋Š”๊ฒŒ์•„๋‹ˆ๋ผ

{state1์ด๋ฆ„, state2์ด๋ฆ„..} ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด props.state1์ด๋ฆ„ ์ด๋ ‡๊ฒŒ ์•ˆํ•ด๋„ ๋จ

๐Ÿ“Œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋งŒ๋“ค๊ธฐ

  1. ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋™์ž‘ ์ „ ์Šคํƒ€์ผ์˜ className ๋งŒ๋“ค๊ธฐ
  2. ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋™์ž‘ ํ›„ ์Šคํƒ€์ผ์˜ className ๋งŒ๋“ค๊ธฐ
  3. transition ์†์„ฑ๋„ ์ถ”๊ฐ€
  4. ์›ํ• ๋•Œ ๋™์ž‘ํ›„์˜ classNam ํƒˆ๋ถ€์ฐฉ
.start {
  opacity : 0
}
.end {
  opacity : 1;
  transition : opacity 0.5s;
}

useEffect๋ฅผ ์‚ฌ์šฉํ•ด์„œ state์•„๋‹ˆ๋ฉด props๊ฐ€ ๋ณ€ํ•  ๋•Œ๋งˆ๋‹ค ์ฝ”๋“œ์‹คํ–‰

//์ด๊ฑด ์•ˆ๋ณด์ž„ end๋ฅผ ๋—๋‹ค๊ฐ€ ๋ถ™์—ฌ์•ผํ•จ
function TabContent({ํƒญ}){

  let [fade, setFade] = useState('')

  useEffect(()=>{
    setFade('end')
  }, [ํƒญ])

  return (
    <div className={'start ' + fade}>
      { [<div>๋‚ด์šฉ0</div>, <div>๋‚ด์šฉ1</div>, <div>๋‚ด์šฉ2</div>][ํƒญ] }
    </div>
  )
}

fade๋ผ๋Š” state๋งŒ๋“ค๊ณ  state์— ๋”ฐ๋ผ className์ด ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ์ž‘์„ฑํ•˜๊ณ  ์›ํ• ๋•Œ fade๋ณ€๊ฒฝ

โ‡’ end๋ผ๋Š” ํด๋ž˜์Šค๋ช…์„ ๋ถ€์ฐฉํ•˜๋Š”๊ฑด ๋งž๋Š”๋ฐ ๋–ผ์—ˆ๋‹ค๊ฐ€ ๋ถ™์—ฌ์•ผ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋ณด์ž„

function TabContent({ํƒญ}){

  let [fade, setFade] = useState('')

  useEffect(()=>{
    setTImeout(()=>{ setFade('end') }, 100) //์‹œ๊ฐ„์ฐจ๋ฅผ ๋‘ 
  return ()=>{
    setFade('') //clean up function ์‚ฌ์šฉ
  }
  }, [ํƒญ])

  return (
    <div className={'start ' + fade}> // `start ${fade}`๊ฐ€๋Šฅ
      { [<div>๋‚ด์šฉ0</div>, <div>๋‚ด์šฉ1</div>, <div>๋‚ด์šฉ2</div>][ํƒญ] }
    </div>
  )
}

setTimeout ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

๋ฆฌ์•กํŠธ 18๋ฒ„์ „์ด์ƒ๋ถ€ํ„ฐ๋Š” automatic batch๋ผ๋Š” ๊ธฐ๋Šฅ์ด ์ƒ๊ฒผ์Œ

state๋ณ€๊ฒฝํ•จ์ˆ˜๋“ค์ด ์—ฐ๋‹ฌ์•„์„œ ์—ฌ๋Ÿฌ๊ฐœ ์ฒ˜๋ฆฌ๋˜์–ด์•ผํ•˜๋ฉด state๋ณ€๊ฒฝํ•จ์ˆ˜๋“ค ๋‹ค ์ฒ˜๋ฆฌํ•˜๊ณ  ๋งˆ์ง€๋ง‰์— ํ•œ๋ฒˆ๋งŒ ์žฌ๋ Œ๋”๋ง๋จ

๊ทธ๋ž˜์„œ โ€˜endโ€™๋กœ ๋ณ€๊ฒฝํ•˜๋Š”๊ฑฐ๋ž‘ โ€˜โ€™์ด๊ฑธ๋กœ ๋ณ€๊ฒฝํ•˜๋Š”๊ฑฐ๋ž‘ ์•ฝ๊ฐ„์˜ ์‹œ๊ฐ„์ฐจ๋ฅผ ๋‘ฌ์•ผํ•จ

ํŠน์ • ์ปดํฌ๋„ŒํŠธ ๋กœ๋“œ์‹œ ํˆฌ๋ช…๋„๊ฐ€ 0์—์„œ 1๋กœ ์„œ์„œํžˆ ์ฆ๊ฐ€ํ•˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์ฃผ๋Š” ๋ฐฉ๋ฒ•

์ œ์ผ ํฐ div๋ฐ•์Šค์— ํด๋ž˜์Šค ํƒˆ๋ถ€์ฐฉ

๋ถ€๋ชจ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž์‹์ปดํฌ๋„ŒํŠธ์˜ ์ž์‹์ปดํฌ๋„ŒํŠธ์— state ์ „์†ก

App โ†’ detailPage โ†’ TabContent ๋กœ props๋ฅผ 2๋ฒˆ ์ „์†ก


์ด๊ฒŒ ๊ท€์ฐฎ์œผ๋ฉด Context API๋ฌธ๋ฒ•(๊ฑฐ์˜ ์‚ฌ์šฉ x) or Redux๊ฐ™์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ

<TabContent tab = {tab} shoes = {props.shoes}></TabContent>

Context API๋ฌธ๋ฒ•์œผ๋กœ props์—†์ด state ๊ณต์œ ํ•˜๊ธฐ

Context API ๋ฌธ๋ฒ•์„ ์“ฐ๋ฉด props์ „์†ก์—†์ด๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅ

context๋Š” ์‰ฝ๊ฒŒ ๋น„์œ ํ•˜์ž๋ฉด state๋ณด๊ด€ํ•จ

(App.js)

export let Context1 = React.createContext();

function App(){
  let [์žฌ๊ณ , ์žฌ๊ณ ๋ณ€๊ฒฝ] = useState([10,11,12]);

	return (
    <Context1.Provider value={ {์žฌ๊ณ , shoes} }>
      <Detail shoes={shoes}/>
    </Context1.Provider>
    
  )
}

๋งŒ๋“  Context๋กœ ์›ํ•˜๋Š” ๊ณณ์„ ๊ฐ์‹ธ๊ณ  ๊ณต์œ ๋ฅผ ์›ํ•˜๋Š” state๋ฅผ value์•ˆ์— ๋‹ค ์ ์œผ๋ฉด ๋จ

๊ฐ์‹ผ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์™€ ๊ทธ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋Š” state๋ฅผ props์ „์†ก์—†์ด ์ง์ ‘ ์‚ฌ์šฉ๊ฐ€๋Šฅ

Context ์•ˆ์— ์žˆ๋˜ state๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด

  1. ๋งŒ๋“ค์–ด๋‘” Context๋ฅผ importํ•ด์ข€
  2. useContext()์•ˆ์— ๋„ฃ์Œ - ํ•ด๋‹น ์ž๋ฆฌ์— ๊ณต์œ ํ–ˆ๋˜ ๋ชจ๋“  state๊ฐ€ ๋‚จ์Œ
(Detail.js)

import {useState, useEffect, useContext} from 'react';
import {Context1} from './../App.js';

function Detail(){
  let {์žฌ๊ณ } = useContext(Context1) //Context๋ฅผ ํ•ด์ฒดํ•ด์ฃผ๋Š” ํ•จ์ˆ˜

  return (
    <div>{์žฌ๊ณ }</div>
  )
}
//์‹ฌ์ง€์–ด Detail ์•ˆ์— ์žˆ๋Š” ๋ชจ๋“  ์ž์‹์ปดํฌ๋„ŒํŠธ๋„ useContext() ์“ฐ๋ฉด ์ž์œ ๋กญ๊ฒŒ ์žฌ๊ณ  state๋ฅผ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Context API๋‹จ์ (์•ˆ์“ฐ๋Š” ์ด์œ )

  1. state๋ณ€๊ฒฝ์‹œ ์“ธ๋ฐ์—†๋Š” ์ปดํฌ๋„ŒํŠธ๊นŒ์ง€ ์ „๋ถ€ ์žฌ๋ Œ๋”๋ง์ด ๋จ
  2. useContext()๋ฅผ ์“ฐ๊ณ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” ๋‚˜์ฃผ์— ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์žฌ์‚ฌ์šฉํ•  ๋•Œ Context๋ฅผ importํ•˜๋Š”๊ฒŒ ๊ท€์ฐฎ์•„์งˆ ์ˆ˜ ์žˆ์Œ

โ‡’ ์ด๊ฑฐ๋ณด๋‹ค Redux๊ฐ™์€ ์™ธ๋ถ€๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•จ

์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ(Redux ์‚ฌ์šฉ)

table๋ ˆ์ด์•„์›ƒ์€ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์—์„œ๊ฐ€์ ธ์˜ด

Redux ์‚ฌ์šฉ์‹œ ์ด์ 

Redux๋Š” props ์—†์ด state๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

Redux๋ฅผ ์„ค์น˜ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด jsํŒŒ์ผ ํ•˜๋‚˜์— state๋“ค์„ ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๊ทธ๊ฑธ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ง์ ‘ ๊บผ๋‚ด์“ธ ์ˆ˜ ์žˆ์Œ

๊ทธ๋ž˜์„œ props์ „์†ก์ด ํ•„์š”์—†์–ด์ง โ†’ ์‚ฌ์ดํŠธ๊ฐ€ ์ปค์ง€๋ฉด ์“ธ ์ˆ˜ ๋ฐ–์— ์—†์Œ

๊ฐœ๋ฐœ์ž ๊ตฌ์ธ์‹œ์—๋„ redux๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ˆ™๋ จ๋„๋ฅผ ๋Œ€๋ถ€๋ถ„ ์š”๊ตฌํ•จ

Redux ์„ค์น˜

npm install @reduxjs/toolkit react-redux

redux toolkit์ด๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๋Š”๊ฑด๋ฐ redux์˜ ๊ฐœ์„ ๋ฒ„์ „(๋ฌธ๋ฒ•์ด ์ข€ ๋” ์‰ฌ์›€)

์„ค์น˜ ์ „ ์ฃผ์˜์‚ฌํ•ญ

  • package.jsonํŒŒ์ผ์— โ€œreactโ€์™€ โ€œreact-domโ€์˜ ๋ฒ„์ „์ด 18.1.x์ด์ƒ์ด์—ฌ์•ผ ์‚ฌ์šฉ๊ฐ€๋Šฅ

๋ฒ„์ „์ด ๋‚ฎ์œผ๋ฉด 18.1.0์ด๋ ‡๊ฒŒ ์ˆ˜์ •ํ•œ๋’ค ํŒŒ์ผ์ €์žฅํ•˜๊ณ  ํ„ฐ๋ฏธ๋„์—์„œ installํ•˜๋ฉด ๋จ

Redux์„ธํŒ…

  1. store.jsํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์•„๋ž˜์ฝ”๋“œ ๋ณต๋ถ™ (state๋“ค์„ ๋ณด๊ด€ํ•˜๋Š” ํŒŒ์ผ)
import { configureStore } from '@reduxjs/toolkit'

export default configureStore({
  reducer: { }
})
  1. index.jsํŒŒ์ผ๊ฐ€์„œ Provider๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ์™€ store.jsํŒŒ์ผ์„ import

๊ทธ๋ฆฌ๊ณ  ๋ฐ‘์— <Provider store={importํ•œ ํŒŒ์ผ}>์ด๊ฑธ๋กœ<App/>์„ ๊ฐ์‹ธ๋ฉด ๋จ

โ‡’ <App>๊ณผ ๊ทธ ๋ชจ๋“  ์ž์‹์ปดํฌ๋„ŒํŠธ๋“ค์€ store.js์— ์žˆ๋˜ state๋ฅผ ๋งˆ์Œ๋Œ€๋กœ ๊บผ๋‚ด์“ธ์ˆ˜์žˆ์Œ

import { Provider } from "react-redux";
import store from './store.js'
//importํ•ด์˜ค๊ณ 
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}> {/**<App>์„ ๊ฐ์‹ธ๊ธฐ*/}
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Provider>
  </React.StrictMode>
);

Redux store์— state ๋ณด๊ด€ํ•˜๋Š” ๋ฐฉ๋ฒ•

  1. createSlice()๋กœ state๋งŒ๋“ค๊ธฐ
  2. configureStore() ์•ˆ์— ๋“ฑ๋ก
import { configureStore, createSlice } from '@reduxjs/toolkit'

//์ƒ์„ฑ
let user = createSlice({
  name : 'user',
  initialState : 'kim'
})

//๋ณด๋‚ด๊ธฐ
export default configureStore({
  reducer: {
    user : user.reducer
  }
})
  1. createSlice( ) ์ƒ๋‹จ์—์„œ import ํ•ด์˜จ ๋‹ค์Œ์—

{ name : 'state์ด๋ฆ„', initialState : 'state๊ฐ’' }ย ์ด๊ฑฐ ๋„ฃ์œผ๋ฉด state ํ•˜๋‚˜ ์ƒ์„ฑ๊ฐ€๋Šฅ

(createSlice( ) ๋Š” useState( ) ์™€ ์šฉ๋„๊ฐ€ ๋น„์Šทํ•˜๋‹ค๊ณ  ๋ณด๋ฉด ๋จ)

  1. state ๋“ฑ๋ก์€ configureStore( ) ์•ˆ์— ๋“ฑ๋ก

{ ์ž‘๋ช… : createSlice๋งŒ๋“ ๊ฑฐ.reducer }ย ์ด๋Ÿฌ๋ฉด ๋“ฑ๋ก ๋

์—ฌ๊ธฐ ๋“ฑ๋กํ•œ state๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉ๊ฐ€๋Šฅ

Redux store์— ์žˆ๋˜ state ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š” ๋ฐฉ๋ฒ•

 (Cart.js)

import { useSelector } from "react-redux"

function Cart(){
  let a = useSelector((state) => { return state } )
//let a = useSelector((state) => state) return๊ณผ ์ค‘๊ด„ํ˜ธ๋Š” ๋™์‹œ์— ์ƒ๋žต๊ฐ€๋Šฅ
//let a = useSelector((state) => state.user ) ์ด๋ ‡๊ฒŒ user๋ฐ์ดํ„ฐ๋งŒ ๊ฐ€์ ธ์˜ฌ์ˆ˜์žˆ์Œ
  console.log(a)

  return (์ƒ๋žต)
}

์•„๋ฌด ์ปดํฌ๋„ŒํŠธ์—์„œ useSelector((state) => { return state } ) ์“ฐ๋ฉด store์— ์žˆ๋˜ ๋ชจ๋“  state๊ฐ€ ๊ทธ ์ž๋ฆฌ์— ๋‚จ์Œ

store์˜ state๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•

state๋ฅผ ์ˆ˜์ •ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ถ€ํ„ฐ store.js์— ๋งŒ๋“ค์–ด๋‘๊ณ  ์ปดํฌ๋„ŒํŠธ์—์„œ ์›ํ•  ๋•Œ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ ์ž‘์„ฑ

  1. store.js์•ˆ์— state์ˆ˜์ •ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ถ€ํ„ฐ ๋งŒ๋“ฌ
let user = createSlice({
  name : 'user',
  initialState : 'kim',
  reducers : {
    changeName(state){
      return 'john ' + state
    }
  }
})

slice ์•ˆ์— reducers : {}์—ด๊ณ  ์•ˆ์— ํ•จ์ˆ˜๋งŒ๋“ฌ

ํ•จ์ˆ˜์— ํŒŒ๋ผ๋ฏธํ„ฐ ํ•˜๋‚˜ ์ž‘๋ช…ํ•˜๋ฉด ๊ทธ๊ฑด ๊ธฐ์กด state๊ฐ€ ๋จ

return ์šฐ์ธก์— ์ƒˆ๋กœ์šด state์ž…๋ ฅํ•˜๋ฉด๊ทธ๊ฑธ๋กœ ๊ธฐ์กด state๋ฅผ ๊ฐˆ์•„์น˜์›Œ์คŒ

  1. ๋‹ค๋ฅธ๊ณณ์—์„œ ์“ฐ๊ธฐ์ข‹๊ฒŒ export
export let { changeName } = user.actions

slice์ด๋ฆ„.actions ๋ผ๊ณ  ์ ์œผ๋ฉด state๋ณ€๊ฒฝํ•จ์ˆ˜๊ฐ€ ์ „๋ถ€ ํ•ด๋‹น ์ž๋ฆฌ์— ์ถœ๋ ฅ

๊ทธ๊ฑธ ๋ณ€์ˆ˜์— ์ €์žฅํ–ˆ๋‹ค๊ฐ€ exportํ•˜๋ผ๋Š” ๋œป

  1. ์›ํ•  ๋•Œ importํ•ด์„œ ์‚ฌ์šฉ / dispatch()๋กœ ๊ฐ์‹ธ์„œ ์‚ฌ์šฉํ•ด์•ผํ•จ
(Cart.js)

import { useDispatch, useSelector } from "react-redux"
import { changeName } from "./../store.js"

(์ƒ๋žต) 
let dispatch = useDispatch()

<button onClick={()=>{
  dispatch(changeName())
}}>๋ฒ„ํŠผ์ž„</button>

store.js์—์„œ ์›ํ•˜๋Š” state๋ณ€๊ฒฝํ•จ์ˆ˜ ๊ฐ€์ ธ์˜ค๊ณ 

useDispatch๋ฅผ importํ•˜๊ณ 

dispatch(state๋ณ€๊ฒฝํ•จ์ˆ˜()) ์ด๋ ‡๊ฒŒ ๊ฐ์‹ธ์„œ ์‹คํ–‰ํ•˜๋ฉด state๋ฅผ ๋ณ€๊ฒฝํ•ด์คŒ

โ‡’ state์ˆ˜์ •ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์„œ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•˜๋Š” ์ด์œ 

์ปดํฌ๋„ŒํŠธ์—์„œ state๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜๊ฒŒ๋˜๋ฉด ๋‹น์žฅ์€ ํŽธํ•˜์ง€๋งŒ state๊ฐ€ ์ž˜๋ชป๋ณ€๊ฒฝ๋˜๋Š” ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ๋””๋ฉด

state๋ฅผ ์ˆ˜์ •ํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ชจ๋‘ ๋’ค์ ธ์„œ ์ฐพ์•„์•ผํ•จ

redux state๊ฐ€ array / object์ธ ๊ฒฝ์šฐ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด

{name : โ€˜kim, age : 20} ์ธ ์ž๋ฃŒ์—์„œ kim โ†’ park ์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•

return ์˜ค๋ฅธ์ชฝ์— ์ ์€๊ฑธ๋กœ ๊ธฐ์กด state๋ฅผ ๊ฐˆ์•„์น˜์›Œ์คŒ

let user = createSlice({
  name : 'user',
  initialState : {name : 'kim', age : 20},
  reducers : {
    changeName(state){
	  state.name = 'park'
      return {name : 'park', age : 20} //๋ณดํ†ต ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉ ์•ˆํ•จ
    }
  }
})

state๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜๋ผ๊ณ ํ•ด๋„ ๋ณ€๊ฒฝ ์ž˜๋จ

state๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜๋Š” ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด๋„ ์ž˜ ๋ณ€๊ฒฝ๋˜๋Š” ์ด์œ ๋Š”

Immer.js ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ state ์‚ฌ๋ณธ์„ ํ•˜๋‚˜ ๋” ์ƒ์„ฑํ•ด์ค€ ๋•๋ถ„์ธ๋ฐ Redux ์„ค์น˜ํ•˜๋ฉด ๋”ธ๋ ค์™€์„œ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊ฒฐ๋ก ์€ array/object ์ž๋ฃŒ์˜ ๊ฒฝ์šฐ state๋ณ€๊ฒฝ์€

state๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•ด๋ฒ„๋ ค๋„ ์ž˜ ๋˜๋‹ˆ๊นŒ ์ง์ ‘ ์ˆ˜์ •ํ•˜์‹ญ์‹œ์˜ค.

โ‡’ ๋ณดํ†ต state๋ฅผ ๋งŒ๋“ค ๋•Œ ๋ฌธ์ž๋‚˜ ์ˆซ์ž ํ•˜๋‚˜๋งŒ ํ•„์š”ํ•ด๋„ redux์—์„  ์ผ๋ถ€๋Ÿฌ object์•„๋‹ˆ๋ฉด array์— ๋‹ด๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Œ ์™œ๋ƒํ•˜๋ฉด ์ˆ˜์ •์ด ํŽธ๋ฆฌํ•ด์ง€๊ธฐ ๋•Œ๋ฌธ

state ๋ณ€๊ฒฝํ•จ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ํ•„์š”ํ•˜๋ฉด

ํŒŒ๋ผ๋ฏธํ„ฐ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉ๊ฐ€๋Šฅ

let user = createSlice({
  name : 'user',
  initialState : {name : 'kim', age : 20},
  reducers : {
    increase(state, action){
      state.age += action.payload
    }
  }
})

ํŒŒ๋ผ๋ฏธํ„ฐ์ž…๋ ฅ์„ ํ•ด์„œ ํ•จ์ˆ˜์‚ฌ์šฉ์ด ๊ฐ€๋Šฅ

ํŒŒ๋ผ๋ฏธํ„ฐ ์ž๋ฆฌ์— ๋„ฃ์€ ์ž๋ฃŒ๋“ค์€ .payloadํ•˜๋ฉด ๋‚˜์˜ด

๋ณดํ†ต ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ action ์œผ๋กœ ์ž‘๋ช… ๋งŽ์ดํ•จ

action.typeํ•˜๋ฉด state๋ณ€๊ฒฝํ•จ์ˆ˜ ์ด๋ฆ„ ๋‚˜์˜ด

action.payloadํ•˜๋ฉด ํŒŒ๋ผ๋ฏธํ„ฐ ๋‚˜์˜ด

๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด ์ˆ˜๋Ÿ‰ +1๋˜๋Š” ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

๋ฒ„ํŠผ๋ˆ„๋ฅด๋ฉด state๋ฅผ ์ˆ˜์ •ํ•ด์•ผํ•˜๋‹ˆ state๋ฅผ +1ํ•ด์ฃผ๋Š” ์ˆ˜์ •ํ•จ์ˆ˜๋ถ€ํ„ฐ ์ž‘์„ฑํ•˜๊ณ  export / import

let cart = createSlice({
  name : 'cart',
  initialState : [
    {id : 0, name : 'White and Black', count : 2},
    {id : 2, name : 'Grey Yordan', count : 1}
  ],
  reducers : {
    addCount(state, action){
      state[action.payload].count++
    }
  }
})

์ •ํ™•ํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋ ค๋ฉด ๋ฒ„ํŠผ๋ˆ„๋ฅด๋ฉด ๋ˆ„๋ฅธ ์ƒํ’ˆid๋ฅผ ๊ฐ€์ ธ์™€์„œ ๊ฐ€์ ธ์˜จ ์ƒํ’ˆ id์™€ ๊ฐ™์€ id๋ฅผ ๊ฐ€์ง„ ์ƒํ’ˆ์„ state์—์„œ ์ฐพ์•„์„œ ๊ทธ๊ฑธ +1ํ•˜๋„๋ก ์ฝ”๋“œ์ž‘์„ฑ

โ‡’ ์ด๋ ‡๊ฒŒ ํ•ด์•ผ ์ƒํ’ˆ์ˆœ์„œ ์ •๋ ฌ ๋“ฑ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€Œ์–ด๋„ ์ž˜ ๋™์ž‘ํ•จ

  1. ๋ฒ„ํŠผ๋ˆ„๋ฅด๋ฉด ํ•ด๋‹น ์ƒํ’ˆ์˜ id๋ฅผ payload๋กœ ์ „์†ก
dispatch(addCount(state.cart[i].id))
  1. โ€˜payload์™€ ๊ฐ™์€ id๋ฅผ ๊ฐ€์ง„ ์ƒํ’ˆ์„ ์ฐพ์•„์„œ +1 ํ•ด๋‹ฌ๋ผ๊ณ  ์ฝ”๋“œ์ž‘์„ฑ (๋ชจ๋ฅด๋ฉด ๊ตฌ๊ธ€๊ฒ€์ƒ‰)

findIndex()๋Š” array๋’ค์— ๋ถ™์ผ ์ˆ˜ ์žˆ์Œ

์•ˆ์— ์ฝœ๋ฐฑํ•จ์ˆ˜๋„ฃ๊ณ  return๋’ค์— ์กฐ๊ฑด์‹์„ ๋„ฃ์œผ๋ฉด๋Œ

ํŒŒ๋ผ๋ฏธํ„ฐa๋Š” array์•ˆ์— ์žˆ๋˜ ํ•˜๋‚˜ํ•˜๋‚˜์˜ ์ž๋ฃŒ

array์— ์žˆ๋–ค ์ž๋ฃŒ๋ฅผ ๋‹ค ๊บผ๋‚ด์„œ ์กฐ๊ฑด์‹์— ๋Œ€์ž…ํ•ด๋ณด๊ณ  ์กฐ๊ฑด์‹์ด ์ฐธ์ด๋ฉด ๊ทธ๊ฒŒ ๋ช‡๋ฒˆ์งธ ์ž๋ฃŒ์ธ์ง€ ๋ฐ˜ํ™˜ํ•ด์คŒ

let cart = createSlice({
  name : 'cart',
  initialState : [
    {id : 0, name : 'White and Black', count : 2},
    {id : 2, name : 'Grey Yordan', count : 1}
  ],
  reducers : {
    addCount(state, action){
      let num = state.findIndex((a)=>{ 
				return a.id === action.payload })
      state[num].count++
    }
  }
})

์ฃผ๋ฌธ๋ฒ„ํŠผ๋ˆ„๋ฅด๋ฉด state์— ์ƒˆ๋กœ์šด ์ƒํ’ˆ์ถ”๊ฐ€

state๋ณ€๊ฒฝํ•จ์ˆ˜๋งŒ๋“ค๊ณ  exportํ•˜๊ณ  importํ•ด์„œ ์‚ฌ์šฉ

let cart = createSlice({
  name : 'cart',
  initialState : [
    {id : 0, name : 'White and Black', count : 2},
    {id : 2, name : 'Grey Yordan', count : 1}
  ],
  reducers : {
    addCount(state, action){
      state[action.payload].count++
    },
    addItem(state, action){
      state.push(action.payload)
    }
  }
})
(Detail.js)

<div className="col-md-6">
  <h4 className="pt-5">{findItem.title}</h4>
  <p>{findItem.content}</p>
  <p>{findItem.price}</p>
  <button className="btn btn-danger" onClick={()=>{
    //console.log(findItem.title)
    dispatch(addStock( {id : findItem.id, name : findItem.title, count : 2} ))}}>์ฃผ๋ฌธํ•˜๊ธฐ</button>
</div></div>

/cart์ž…๋ ฅํ•ด์„œ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•˜๋ฉด ํŽ˜์ด์ง€๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ๋˜๊ธฐ๋•Œ๋ฌธ์— state๋„ ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ๋Œ์•„๊ฐ โ†’ ๋ผ์šฐํ„ฐ๋ฒ„ํŠผ์„ ๋งŒ๋“ค์–ด์„œ ํŽ˜์ด์ง€ ์ด๋™ํ•ด์•ผํ•จ

๋ฆฌ์•กํŠธ์—์„œ ์ž์ฃผ ์“ฐ๋Š” if๋ฌธ ์ž‘์„ฑํŒจํ„ด 5๊ฐœ

์ง€๊ธˆ๊นŒ์ง€๋Š” ์‚ผํ•ญ์—ฐ์‚ฐ์ž๋งŒ ์‚ฌ์šฉ

  • ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ์“ฐ๋Š” if / else
function Component() {
  if ( true ) {
    return <p>์ฐธ์ด๋ฉด ๋ณด์—ฌ์ค„ HTML</p>;
  } else {
    return null;
  }
}
// ์•„๋ž˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋ฉด else์ƒ๋žต์ด ๊ฐ€๋Šฅํ•จ
function Component() {
  if ( true ) {
    return <p>์ฐธ์ด๋ฉด ๋ณด์—ฌ์ค„ HTML</p>;
  } 
  return null;
}

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ if๋ฌธ์€ return() ์•ˆ์˜ JSX ๋‚ด์—์„œ๋Š” ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅ

<div> if () {} </div> ๋Š” ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณดํ†ต return + JSX ์ „์ฒด๋ฅผ ๋ฑ‰์–ด๋‚ด๋Š” if๋ฌธ์„ ์ž‘์„ฑํ•ด์„œ ์‚ฌ์šฉ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ function์•ˆ์—์„  return์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ ๋งŒ๋‚˜๋ฉด return ๋ฐ‘์— ์žˆ๋Š” ์ฝ”๋“œ๋Š” ๋”์ด์ƒ ์‹คํ–‰๋˜์ง€ ์•Š์Œ

if -> else if -> else ์ด๋ ‡๊ฒŒ ๊ตฌ์„ฑ๋œ ์กฐ๊ฑด๋ฌธ๋„ if ๋‘๊ฐœ๋กœ ์ถ•์•ฝ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • JSX์•ˆ์—์„œ ์“ฐ๋Š” ์‚ผํ•ญ์—ฐ์‚ฐ์ž

์กฐ๊ฑด๋ฌธ ? ์ฐธ์ผ๋•Œ ์‹คํ–‰ํ•  ์ฝ”๋“œ : ๊ฑฐ์ง“์ผ ๋•Œ ์‹คํ–‰ํ•  ์ฝ”๋“œ

function Component() {
  return (
    <div>
      {
        1 === 1
        ? <p>์ฐธ์ด๋ฉด ๋ณด์—ฌ์ค„ HTML</p>
        : null
      }
    </div>
  )
}
  • &&์—ฐ์‚ฐ์ž๋กœ if ์—ญํ•  ๋Œ€์‹ 
true && '์•ˆ๋…•'; //์•ˆ๋…• ์ถœ๋ ฅ
false && '์•ˆ๋…•'; //false ์ถœ๋ ฅ
true && false && '์•ˆ๋…•'; //false ์ถœ๋ ฅ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ทธ๋ƒฅ &&๋กœ ์—ฐ๊ฒฐ๋œ ๊ฐ’๋“ค ์ค‘์— ์ฒ˜์Œ ๋“ฑ์žฅํ•˜๋Š” false๊ฐ’์„ ์ฐพ์•„์ฃผ๊ณ  ๊ทธ๊ฒŒ ์•„๋‹ˆ๋ฉด ๋งˆ์ง€๋ง‰๊ฐ’์„ ๋‚จ๊ฒจ์คŒ

//์•„๋ž˜ ๋‘๊ฐœ๋Š” ๋™์ผํ•œ ์—ญํ• 
function Component() {
  return (
    <div>
      {
        1 === 1
        ? <p>์ฐธ์ด๋ฉด ๋ณด์—ฌ์ค„ HTML</p>
        : null
      }
    </div>
  )
} 

function Component() {
  return (
    <div>
      { 1 === 1 && <p>์ฐธ์ด๋ฉด ๋ณด์—ฌ์ค„ HTML</p> }
    </div>
  )
}

&&์—ฐ์‚ฐ์ž๋กœ ์กฐ๊ฑด์‹๊ณผ ์˜ค๋ฅธ์ชฝ JSX์ž๋ฃŒ๋ฅผ ๋น„๊ต

์™ผ์ชฝ ์กฐ๊ฑด์‹์ด true๋ฉด ์˜ค๋ฅธ์ชฝ JSX๊ฐ€ ๊ทธ ์ž๋ฆฌ์— ๋‚จ์Œ

์™ผ์ชฝ ์กฐ๊ฑด์‹์ด false๋ฉด false๊ฐ€ ๋‚จ์Œ (false๊ฐ€ ๋‚จ์œผ๋ฉด HTML๋กœ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Œ)

โ€˜๋งŒ์•ฝ ๋ณ€์ˆ˜๊ฐ€ ์ฐธ์ด๋ฉด

๋ฅผ ์ด ์ž๋ฆฌ์— ์ถœ๋ ฅํ•˜๊ณ  ์•„๋‹ˆ๋ฉด nullโ€™ ์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ ์ž์ฃผ ์‚ฌ์šฉ

  • switch / case ์กฐ๊ฑด๋ฌธ

๊ธฐ๋ณธ ๋ฌธ๋ฒ•์ธ๋ฐ if๋ฌธ์ด ์ค‘์ฒฉํ•ด์„œ ์—ฌ๋Ÿฌ๊ฐœ ๋‹ฌ๋ ค์žˆ๋Š” ๊ฒฝ์šฐ ๊ฐ€๋” ์‚ฌ์šฉ

function Component2(){
  var user = 'seller';
  switch (user){
    case 'seller' :
      return <h4>ํŒ๋งค์ž ๋กœ๊ทธ์ธ</h4>
    case 'customer' :
      return <h4>๊ตฌ๋งค์ž ๋กœ๊ทธ์ธ</h4>
    default : 
      return <h4>๊ทธ๋ƒฅ ๋กœ๊ทธ์ธ</h4>
  }
}

1.ย switch (๊ฒ€์‚ฌํ• ๋ณ€์ˆ˜){}ย ์ด๊ฑฐ๋ถ€ํ„ฐ ์ž‘์„ฑํ•˜๊ณ 

  1. ๊ทธ ์•ˆ์—ย case ๊ฒ€์‚ฌํ• ๋ณ€์ˆ˜๊ฐ€์ด๊ฑฐ๋ž‘์ผ์น˜ํ•˜๋ƒ :ย ๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

  2. ๊ทธ๋ž˜์„œ ์ด๊ฒŒ ์ผ์น˜ํ•˜๋ฉด case : ๋ฐ‘์— ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด์ค๋‹ˆ๋‹ค.

4.ย default :ย ๋Š” ๊ทธ๋ƒฅ ๋งจ ๋งˆ์ง€๋ง‰์— ์“ฐ๋Š” else๋ฌธ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

์žฅ์  : if๋ฌธ์„ ์—ฐ๋‹ฌ์•„ ์“ธ ๋•Œ ์ฝ”๋“œ๊ฐ€ ์•ฝ๊ฐ„ ์ค„์–ด๋“ฌ / ๋‹จ์  : ์กฐ๊ฑด์‹๋ž€์—์„œ ๋ณ€์ˆ˜ ํ•˜๋‚˜๋งŒ ๊ฒ€์‚ฌ ๊ฐ€๋Šฅ

  • object / array ์ž๋ฃŒํ˜• ์‘์šฉ

๊ฒฝ์šฐ์— ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ htmlํƒœ๊ทธ๋“ค์„ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— if๋ฌธ ์—ฌ๋Ÿฌ๊ฐœ ํ˜น์€ ์‚ผํ•ญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์•„๋ž˜์ฒ˜๋Ÿผ๋„ ์ž‘์„ฑ ๊ฐ€๋Šฅ

ํ˜„์žฌย state๊ฐ€ info๋ฉด <p>์ƒํ’ˆ์ •๋ณด</p>

ํ˜„์žฌย state๊ฐ€ shipping์ด๋ฉด <p>๋ฐฐ์†ก์ •๋ณด</p>

ํ˜„์žฌ state๊ฐ€ refund๋ฉด <p>ํ™˜๋ถˆ์•ฝ๊ด€</p>

function Component() {
  var ํ˜„์žฌ์ƒํƒœ = 'info';
  return (
    <div>
      {
        { 
           info : <p>์ƒํ’ˆ์ •๋ณด</p>,
           shipping : <p>๋ฐฐ์†ก๊ด€๋ จ</p>,
           refund : <p>ํ™˜๋ถˆ์•ฝ๊ด€</p>
        }[ํ˜„์žฌ์ƒํƒœ]
      }

    </div>
  )
}

์›๋ž˜ JSX ์ƒ์—์„œ html ํƒœ๊ทธ๋“ค์€ ์ €๋ ‡๊ฒŒ object์— ๋‹ด๋“ , array์— ๋‹ด๋“  ์•„๋ฌด ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค.

์•”ํŠผ ์ด๋ ‡๊ฒŒ object ์ž๋ฃŒํ˜•์œผ๋กœ HTML์„ ๋‹ค ์ •๋ฆฌํ•ด์„œ ๋‹ด์€ ๋‹ค์Œ

๋งˆ์ง€๋ง‰์— object{} ๋’ค์— [] ๋Œ€๊ด„ํ˜ธ๋ฅผ ๋ถ™์—ฌ์„œย "key๊ฐ’์ดย ํ˜„์žฌ์ƒํƒœ์ธ ์ž๋ฃŒ๋ฅผ ๋ฝ‘๊ฒ ์Šต๋‹ˆ๋‹ค"ย ๋ผ๊ณ  ์จ๋†“๋Š”๊ฒ๋‹ˆ๋‹ค.

var ํƒญUI = {  //๋ณดํ†ต var๋ณ€์ˆ˜๋Œ€์‹  state๋กœ ์‚ฌ์šฉํ•จ
  info : <p>์ƒํ’ˆ์ •๋ณด</p>,
  shipping : <p>๋ฐฐ์†ก๊ด€๋ จ</p>,
  refund : <p>ํ™˜๋ถˆ์•ฝ๊ด€</p>
}

function Component() {
  var ํ˜„์žฌ์ƒํƒœ = 'info';
  return (
    <div>
      {
        ํƒญUI[ํ˜„์žฌ์ƒํƒœ]
      }
    </div>
  )
}

localStorage ๋ฌธ๋ฒ•

jsํŒŒ์ผ ์•„๋ฌด๋ฐ์„œ๋‚˜ localStorage๋ฌธ๋ฒ•์„ ์“ฐ๋ฉด localStorage์— ๋ฐ์ดํ„ฐ์ž…์ถœ๋ ฅ ๊ฐ€๋Šฅ

๊ธฐ์กด ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋Š”๊ฑด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ๋•Œ๋ฌธ์— ๊บผ๋‚ด์„œ ์ˆ˜์ •ํ•˜๊ณ  ๋‹ค์‹œ ์ €์žฅ

localStorage.setItem('๋ฐ์ดํ„ฐ์ด๋ฆ„', '๋ฐ์ดํ„ฐ'); //์ €์žฅ
localStorage.getItem('๋ฐ์ดํ„ฐ์ด๋ฆ„'); //์ฝ๊ธฐ
localStorage.removeItem('๋ฐ์ดํ„ฐ์ด๋ฆ„') //์‚ญ์ œ

localStorage์— array/object ์ž๋ฃŒ๋ฅผ ์ €์žฅํ•˜๋ ค๋ฉด

๊ทธ๋ƒฅํ•˜๋ฉด ์ž๋ฃŒ๊ฐ€ ๊นจ์ง€๊ธฐ ๋•Œ๋ฌธ์— JSON์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ ์ €์žฅ

localStorage.setItem('obj', JSON.stringify({name:'kim'}) );
//๋ณ€ํ™˜ํ•ด์„œ ์ €์žฅ
var a = localStorage.getItem('obj'); //data๊ฐ€์ ธ์˜ด
var b = JSON.parse(a) //JSON -> array/object

์ตœ๊ทผ ๋ณธ ์ƒํ’ˆ ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

  1. detail ํŽ˜์ด์ง€์— ์ ‘์†ํ•˜๋ฉด
  2. ํ˜„์žฌ ํŽ˜์ด์ง€์˜ ์ƒํ’ˆid๋ฅผ ๊ฐ€์ ธ์™€์„œ
  3. localStorage์— ์žˆ๋Š” watchํ•ญ๋ชฉ์— ์ถ”๊ฐ€
(Detail.js)

useEffect(()=>{
  let ๊บผ๋‚ธ๊ฑฐ = localStorage.getItem('watched')
  ๊บผ๋‚ธ๊ฑฐ = JSON.parse(๊บผ๋‚ธ๊ฑฐ)
  ๊บผ๋‚ธ๊ฑฐ.push(์ฐพ์€์ƒํ’ˆ.id)
  localStorage.setItem('watched', JSON.stringify(๊บผ๋‚ธ๊ฑฐ))
}, [])

์ค‘๋ณต์ œ๊ฑฐ

์ƒํ’ˆid๊ฐ€ ์ด๋ฏธ [] ์•ˆ์— ์กด์žฌํ•˜๋ฉด ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๋„๋ก if๋ฌธ ์ž‘์„ฑ ํ•˜๊ฑฐ๋‚˜

Set์ž๋ฃŒํ˜•์œผ๋กœ array์˜ ์ค‘๋ณต ์ œ๊ฑฐ

(Detail.js)

useEffect(()=>{
  let ๊บผ๋‚ธ๊ฑฐ = localStorage.getItem('watched')
  ๊บผ๋‚ธ๊ฑฐ = JSON.parse(๊บผ๋‚ธ๊ฑฐ)
  ๊บผ๋‚ธ๊ฑฐ.push(์ฐพ์€์ƒํ’ˆ.id)

  //Set์œผ๋กœ ๋ฐ”๊ฟจ๋‹ค๊ฐ€ ๋‹ค์‹œ array๋กœ ๋งŒ๋“ค๊ธฐ
  ๊บผ๋‚ธ๊ฑฐ = new Set(๊บผ๋‚ธ๊ฑฐ)
  ๊บผ๋‚ธ๊ฑฐ = Array.from(๊บผ๋‚ธ๊ฑฐ) //๋‹ค์‹œ array๋กœ
  localStorage.setItem('watched', JSON.stringify(๊บผ๋‚ธ๊ฑฐ))
}, [])

localStorage์— state๋ฅผ ์ž๋™์ €์žฅ๋˜๊ฒŒ ๋งŒ๋“ค๊ณ  ์‹ถ์œผ๋ฉด

redux-persist ์ด๋Ÿฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ํ•ด์„œ ์“ฐ๋ฉด redux store ์•ˆ์— ์žˆ๋Š” state๋ฅผ ์ž๋™์œผ๋กœ localStorage์— ์ €์žฅํ•ด์ค๋‹ˆ๋‹ค.

state ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๊ทธ์— ๋งž๊ฒŒ localStorage ์—…๋ฐ์ดํŠธ๋„ ์•Œ์•„์„œ ํ•ด์คŒ

ํ•˜์ง€๋งŒ ์…‹ํŒ…๋ฌธ๋ฒ• ๋ณต์žกํ•˜๊ณ  ๊ท€์ฐฎ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์š”์ฆ˜์€ ์‹ ๊ทœ ์‚ฌ์ดํŠธ๋“ค์€ Redux ๋Œ€์‹  Jotai, Zustand ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š”๋ฐ ์…‹ํŒ…๋„ ๊ฑฐ์˜ ํ•„์š”์—†๊ณ  ๋ฌธ๋ฒ•์ด ํ›จ์”ฌ ๋” ์‰ฌ์šฐ๋‹ˆ๊นŒ์š”.

๊ทธ๋ฆฌ๊ณ  ๊ทธ๋Ÿฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค๋„ ์•„๋งˆ localStorage ์ž๋™์ €์žฅ๊ธฐ๋Šฅ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

react-query ์—…๋ฐ์ดํŠธ ์‚ฌํ•ญ

(์—…๋ฐ์ดํŠธ ์‚ฌํ•ญ)ย ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„์ด react-query์—์„œ @tanstack/react-query๋กœ ๋ฐ”๋€Œ์–ด์„œ ์•„๋ž˜ ์ •๋ฆฌํ•œ๊ฒƒ๋“ค์—์„œ ๋ณ€๊ฒฝํ•ด์„œ ์‚ฌ์šฉํ• ๊ฒƒ

npm install @tanstack/react-query //์„ค์น˜์‹œ ๋ณ€๊ฒฝ์‚ฌํ•ญ
//import์‹œ ๋ณ€๊ฒฝ์‚ฌํ•ญ
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query'
//useQuery ์“ธ๋•Œ '์ž‘๋ช…' ๋ง๊ณ  ['์ž‘๋ช…']์œผ๋กœ ๋ฐ”๋€œ
useQuery(['์ž‘๋ช…'],

ajax์š”์ฒญํ•˜๋‹ค๋ณด๋ฉด ํ•ด๋‹น ๊ธฐ๋Šฅ๋“ค์ด ๊ฐ€๋” ํ•„์š”ํ•ด์ง

-๋ช‡์ดˆ๋งˆ๋‹ค ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๊ฒŒ ํ•˜๋ ค๋ฉด

-์š”์ฒญ ์‹คํŒจ์‹œ ๋ช‡์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ์žฌ์‹œ๋„

-๋‹ค์Œ ํŽ˜์ด์ง€ ๋ฏธ๋ฆฌ ๊ฐ€์ ธ์˜ค๊ธฐ

-ajax ์„ฑ๊ณต/์‹คํŒจ ์‹œ ๊ฐ๊ฐ ๋‹ค๋ฅธ html์„ ๋ณด์—ฌ์ฃผ๋ ค๋ฉด

โ‡’์ง์ ‘ ๊ฐœ๋ฐœํ•ด๋„๋˜์ง€๋งŒ ๊ท€์ฐฎ์œผ๋ฉด react-query๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•ด์„œ ์‚ฌ์šฉํ•ด๋„๋จ

sns, ์ฝ”์ธ๊ฑฐ๋ž˜์†Œ ๊ฐ™์€ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ค˜์•ผํ•˜๋Š” ์‚ฌ์ดํŠธ๋“ค์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ์œ ์šฉํ•˜๊ณ  ๋‚˜๋จธ์ง€ ์‚ฌ์ดํŠธ๋“ค์€ ๋”ฑํžˆ ์“ธ๋ฐ๋Š” ์—†์Œ

ํ„ฐ๋ฏธ๋„์—์„œ npm install react-queryํ•˜๊ณ 

index.jsํŒŒ์ผ์—์„œ 1๋ฒˆ 2๋ฒˆ 3๋ฒˆ ์ˆœ์„œ๋Œ€๋กœ

import { QueryClient, QueryClientProvider } from "react-query"  //1๋ฒˆ
const queryClient = new QueryClient()   //2๋ฒˆ

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <QueryClientProvider client={queryClient}>  //3๋ฒˆ
    <Provider store={store}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Provider>
  </QueryClientProvider>
);

react-query๋กœ ajax์š”์ฒญํ•˜๋Š” ๋ฐฉ๋ฒ•

๊ทธ๋ƒฅ ์š”์ฒญํ•ด๋„๋˜์ง€๋งŒ react-query๋ฅผ ์จ์„œ ajax์š”์ฒญ์„ ๋‚ ๋ฆฌ๋ฉด ๋” ํŽธ๋ฆฌํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณต / useQuery()๋กœ ajax์š”์ฒญ์„ ๊ฐ์‹ธ์„œ ์‚ฌ์šฉ

function App(){
  let result = useQuery('์ž‘๋ช…', ()=>
    axios.get('https://codingapple1.github.io/userdata.json')
    .then((a)=>{ return a.data })
  )
}

react-query ์žฅ์ 

์žฅ์ 1. ajax ์š”์ฒญ ์„ฑ๊ณต/์‹คํŒจ/๋กœ๋”ฉ์ค‘ ์ƒํƒœ๋ฅผ ์‰ฝ๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

function App(){
  let result = useQuery('์ž‘๋ช…', ()=>
    axios.get('https://codingapple1.github.io/userdata.json')
    .then((a)=>{ return a.data })
  )

  return (
    <div>
      { result.isLoading && '๋กœ๋”ฉ์ค‘' }
      { result.error && '์—๋Ÿฌ๋‚จ' }
      { result.data && result.data.name }
    </div>
  )
}

result๋ผ๋Š” ๋ณ€์ˆ˜์— ajax ํ˜„์žฌ ์ƒํƒœ๊ฐ€ ์•Œ์•„์„œ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

  • ajax์š”์ฒญ์ด ๋กœ๋”ฉ์ค‘์ผ ๋• result.isLoading ์ด true
  • ajax์š”์ฒญ์ด ์‹คํŒจ์‹œ์—” result.error ๊ฐ€ true
  • ajax์š”์ฒญ์ด ์„ฑ๊ณต์‹œ์—” result.data ์•ˆ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์žˆ์Œ

๊ทธ๋ž˜์„œ ajax ๋กœ๋”ฉ์ค‘์ผ ๋• <A/> ๋ณด์ด๊ธฐ / ajax ์„ฑ๊ณต์‹œ์—” <B/> ๋ณด์ด๊ธฐ

์ด๋Ÿฐ๊ฑฐ ์ง์ ‘ ๊ฐœ๋ฐœํ•˜๋ ค๋ฉด state ๋ถ€ํ„ฐ ๋งŒ๋“ค์–ด์•ผ ํ–ˆ์„ํ…๋ฐ ์–˜๋Š” ๊ทธ๋Ÿด ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์žฅ์ 2. ํ‹ˆ๋งŒ๋‚˜๋ฉด ์•Œ์•„์„œ ajax ์žฌ์š”์ฒญํ•ด์ค๋‹ˆ๋‹ค.

ํŽ˜์ด์ง€์—์„œ ์ผ์ •์‹œ๊ฐ„ ๊ฒฝ๊ณผ / ๋‹ค๋ฅธ์ฐฝ์œผ๋กœ ๊ฐ”๋‹ค๊ฐ€ ๋Œ์•„์˜ค๊ฑฐ๋‚˜ ์ด๋Ÿด๋•Œ ์•Œ์•„์„œ ajax์š”์ฒญ์„ ๋‹ค์‹œํ•ด์คŒ / ์žฌ์š”์ฒญ๋„๋Š”๋ฒ•, ์žฌ์š”์ฒญ ๊ฐ„๊ฒฉ ์กฐ์ ˆํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Œ

์žฅ์ 3. ์‹คํŒจ์‹œ ์žฌ์‹œ๋„ ์•Œ์•„์„œ ํ•ด์คŒ

๋ช‡๋ฒˆ ์žฌ์‹œ๋„ํ•˜๊ณ  ์•ˆ๋˜๋ฉด ์˜ค๋ฅ˜๋„์›Œ์คŒ

์žฅ์ 4. ajax๋กœ ๊ฐ€์ ธ์˜จ ๊ฒฐ๊ณผ๋Š” state ๊ณต์œ  ํ•„์š”์—†์Œ

์ง€๊ธˆ App ์ปดํฌ๋„ŒํŠธ์—์„œ ์œ ์ €์ด๋ฆ„ ๊ฐ€์ ธ์˜ค๋Š” ajax ์š”์ฒญ์„ ๋‚ ๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทผ๋ฐ ๊ทธ ์œ ์ €์ด๋ฆ„ ๊ฒฐ๊ณผ๊ฐ€ Detail ์ปดํฌ๋„ŒํŠธ์—๋„ ํ•„์š”ํ•˜๋ฉด?

์œ ์ €์ด๋ฆ„์„ props ์ „์†กํ•˜๋ฉด ๋˜์ง€๋งŒ props ์ „์†ก ํ•„์š”์—†์Œ

Detail ์ปดํฌ๋„ŒํŠธ์—๋‹ค๊ฐ€ ์œ ์ €์ด๋ฆ„ ajax ์š”์ฒญํ•˜๋Š” ์ฝ”๋“œ ๋˜‘๊ฐ™์ด ๋˜ ์ ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

react-query๋Š” ์Šค๋งˆํŠธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ajax ์š”์ฒญ์ด 2๊ฐœ๋‚˜ ์žˆ์œผ๋ฉด 1๊ฐœ๋งŒ ๋‚ ๋ ค์ฃผ๊ณ 

์บ์‹ฑ๊ธฐ๋Šฅ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ ๊ฐ™์€ ajax ์š”์ฒญ์„ ํ•œ ์ ์ด ์žˆ์œผ๋ฉด ๊ทธ๊ฑธ ์šฐ์„  ๊ฐ€์ ธ์™€์„œ ์”๋‹ˆ๋‹ค.

react-query๊ฐ€ ์ฃผ์žฅํ•˜๋Š” ์žฅ์ ์€

server-state (DB ๋ฐ์ดํ„ฐ)๋ฅผ ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ์‹ค์‹œ๊ฐ„ ๋™๊ธฐํ™”ํ•ด์ฃผ๋Š”๊ฑธ ๋„์™€์ค€๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๊ทผ๋ฐ ajax ์š”์ฒญ์„ ๋ช‡์ดˆ๋งˆ๋‹ค ๊ณ„์† ๋‚ ๋ ค์„œ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ์‹์ด๋ผ ์ข€ ๋น„ํšจ์œจ์ ์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹ค์‹œ๊ฐ„์œผ๋กœ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž์ฃผ ๋ณด๋‚ด๋ ค๋ฉด ์›น์†Œ์ผ“์ด๋‚˜ Server-sent events ๊ฐ™์€ ๊ฐ€๋ฒผ์šด ๋ฐฉ์‹๋“ค๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ react-query๋Š” ajax ๊ด€๋ จ ๊ธฐ๋Šฅ๊ฐœ๋ฐœ ํŽธํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ์— ์˜์˜๊ฐ€ ๋” ์žˆ์Šต๋‹ˆ๋‹ค.

RTK Query ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ ์žˆ์Œ

Redux Toolkit ์„ค์น˜ํ•œ ๊ฒฝ์šฐ RTK Query ๋ผ๋Š”๊ฒƒ๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ๋ฐ

๋น„์Šทํ•œ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋งŒ ์…‹ํŒ…ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์ข€ ๋”๋Ÿฝ์Šต๋‹ˆ๋‹ค.

RTK Query๋Š” ์‹ค์€ ๋‹ค๋ฅธ ์šฉ๋„๋กœ๋„ ๋งŽ์ด ์“ฐ๋Š”๋ฐ

ajax ์š”์ฒญํ›„ Redux state ๋ณ€๊ฒฝ์„ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด...

์›๋ž˜ Redux state๋ณ€๊ฒฝํ•จ์ˆ˜ ์•ˆ์—์„  ajax์š”์ฒญํ•˜๋ฉด ์•ˆ๋˜์–ด์„œ ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ทผ๋ฐ ajax ์š”์ฒญํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๋‹ค์–‘ํ•˜๊ณ  ๋งŽ์œผ๋ฉด ์ปดํฌ๋„ŒํŠธ ์•ˆ์˜ ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ง€๊ณ  ๊ด€๋ฆฌ๋„ ๊ท€์ฐฎ์€๋ฐ

๊ทธ๋Ÿฐ๊ฑธ Slice ์•ˆ์—์„œ ๊ด€๋ฆฌ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋„์™€์ค๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ajax ์š”์ฒญํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ 100๋งŒ๊ฐœ ์žˆ์œผ๋ฉด ๊ทธ๊ฑธ ํŽธ๋ฆฌํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค๋‹ˆ๋‹ค.

๊ทผ๋ฐ ์ฝ”๋“œ๊ฐ€ ์•ฝ๊ฐ„ ๋”๋Ÿฌ์šธ ๋ฟ

profile
ํ”„๋ก ํŠธ์—”๋“œ ๊ณต๋ถ€

0๊ฐœ์˜ ๋Œ“๊ธ€