๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
[๊ฐœ๋ฐœ] Practice/React

[React] props ๋Œ€์‹  redux ์‚ฌ์šฉํ•ด๋ณด๊ธฐ_4

by Connecting-the-dots 2022. 3. 29.
728x90
๋ฐ˜์‘ํ˜•

๐Ÿ’ก ์‹ค์Šต ํฌ์ธํŠธ!

๐Ÿ’œ "์ฃผ๋ฌธํ•˜๊ธฐ" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ ์ƒํ’ˆ์„ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๊ธฐ

  • ์˜ค๋Š˜์€ redux ๋ฅผ ์ด์šฉํ•˜์—ฌ ํŠน์ • ์ƒํ’ˆ์˜ ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ "์ฃผ๋ฌธํ•˜๊ธฐ" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€๋กœ ์ด๋™๋˜๊ณ , ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€์—๋Š” "์ฃผ๋ฌธํ•˜๊ธฐ" ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ๋˜ ์ƒํ’ˆ์ด ์ถ”๊ฐ€๋˜์–ด ๋ณด์—ฌ์ง€๊ฒŒ ํ•ด๋ณด์•˜๋‹ค.
  • ๋‹ค๋งŒ, ์ด๋ฏธ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๊ธด ์ƒํ’ˆ์„ ์ถ”๊ฐ€ ์ฃผ๋ฌธํ•˜๋ฉด ํ–‰์ด ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์ˆ˜๋Ÿ‰๋งŒ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ ์ด ๋ถ€๋ถ„์€ ์•„์ง ๋ฏธ์™„์„ฑ์ด๋ผ ์กฐ๋งŒ๊ฐ„ ์ˆ˜์ •์„ ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

๐Ÿ’œ ์ˆ˜๋Ÿ‰ ์กฐ์ ˆ ๋ฒ„ํŠผ ๊ธฐ๋Šฅ ์ˆ˜์ •ํ•˜๊ธฐ

  • ์ง€๋‚œ๋ฒˆ์— ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€์˜ ์ˆ˜๋Ÿ‰ ์กฐ์ ˆ ๋ฒ„ํŠผ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค ๋•Œ, dispatch ํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ๋ชฐ๋ผ์„œ ์ฒซ๋ฒˆ์งธ ํ•ญ๋ชฉ๋งŒ ๊ธฐ๋Šฅ์ด ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋“œ์ฝ”๋”ฉ์„ ํ–ˆ์—ˆ๋‹ค.
  • ๊ทธ๋ž˜์„œ ์ด๋ฒˆ ์ˆ˜์—… ๋‚ด์šฉ์„ ํ™œ์šฉํ•˜๋ฉด ์ˆ˜๋Ÿ‰ ์กฐ์ ˆ ๋ฒ„ํŠผ ๊ธฐ๋Šฅ๋„ id ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€์„œ ์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•  ๊ฒƒ ๊ฐ™์•„์„œ ๋งŒ๋“ค์–ด๋ณด์•˜๋‹ค.

๐Ÿ’œ ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ ์ฃผ๋ฌธํ•˜๊ธฐ ํด๋ฆญํ•˜๋ฉด ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๋Š” ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

๐Ÿค "์ฃผ๋ฌธํ•˜๊ธฐ" ๋ฒ„ํŠผ UI ๋งŒ๋“ค๊ธฐ

<button className="btn btn-danger mx-1">์ฃผ๋ฌธํ•˜๊ธฐ</button>
  • "์ฃผ๋ฌธํ•˜๊ธฐ" ๋ฒ„ํŠผ์€ Bootstrap ์„ ์ด์šฉํ•˜์—ฌ ์ด์ „์— ์ด๋ฏธ ๋งŒ๋“ค์–ด๋‘์—ˆ๋‹ค.

๐Ÿค "์ฃผ๋ฌธํ•˜๊ธฐ" ๋ฒ„ํŠผ ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

let defaultData = [
  { id : 1, name : 'Red Knit', quan : 2 },
  { id : 0, name : 'White and Black', quan : 1 },
  { id : 3, name : 'Flowey', quan : 3 }  
]
  • ๋ธŒ๋ผ์šฐ์ €์—์„œ "์ฃผ๋ฌธํ•˜๊ธฐ" ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€ ๋ชฉ๋ก์— ํ’ˆ๋ชฉ์ด ์ถ”๊ฐ€๋˜์–ด ๋ณด์—ฌ์ง€๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, "์ฃผ๋ฌธํ•˜๊ธฐ" ๋ฒ„ํŠผ์˜ onClick ์†์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ ์œ„ defaultData ์— object ํ˜•ํƒœ๋กœ ์ƒ์„ธ ํŽ˜์ด์ง€์˜ ํ’ˆ๋ชฉ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

1. reducer ์— ๋ฐ์ดํ„ฐ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ •์˜ํ•˜๊ธฐ

function reducer(state = defaultData, action) {

  if (action.type === 'addItem') {
      let item = action.payload.findId;
      let newState = [...state];
        newState.push({
          id : item.id,
          name : item.title,
          quan : 1
        })
        return newState;
        
    } else if (action.type === 'plus') {
    
      let id = action.payload;
      let newState = [...state];
      newState[id].quan++;
      return newState;
      
    } else if (action.type === 'minus'){
    
      let id = action.payload;
      let newState = [...state];
      if (newState[id].quan > 0) {
        newState[id].quan--;
      }
      return newState;
      
    } else {
    
      return state;
      
    }
}
  • ์ง€๋‚œ ๋ฒˆ์— + / - ๋ฒ„ํŠผ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ–ˆ๋˜ reducer ์—๋‹ค๊ฐ€ ์ด๋ฒˆ์—๋Š” 'addItem' ์œผ๋กœ if ๋ฌธ์„ ์ถ”๊ฐ€์ž‘์„ฑํ•ด์ฃผ์—ˆ๋‹ค.
  • ์ฝ”๋“œ๋ฅผ ํ•ด์„ํ•˜์ž๋ฉด, 'addItem' ์ด๋ผ๋Š” ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด newState ๋ผ๋Š” defaultData ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค์–ด์ฃผ๊ณ  ์—ฌ๊ธฐ์— ์ „์†ก๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด๋‹ฌ๋ผ๋Š” ๊ฒƒ์ด๋‹ค.

 

2. dispatch ์‚ฌ์šฉํ•˜๊ธฐ

<button className="btn btn-danger mx-1" onClick={()=>{props.dispatch({ type : 'addItem' })}}>์ฃผ๋ฌธํ•˜๊ธฐ</button>
  • ์ด์ œ Detail.js ํŒŒ์ผ์˜ "์ฃผ๋ฌธํ•˜๊ธฐ" ๋ฒ„ํŠผ์— 'addItem' ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ํ•ด๋‹น if ๋ฌธ ์•ˆ์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•ด์ฃผ๋Š” dispatch ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

 

function Store(state) {

  return {
      data : state.reducer,
      alert : state.reducer2
  }

}

export default connect(Store)(Detail);
  • ๊ทธ๋ฆฌ๊ณ  dispatch ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ๊ผญ ํ•˜๋‹จ์— state ๋ฅผ props ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ํ•จ์ˆ˜์™€ export default connect() ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์ž! 

 

3. dispatch ํ•  ๋•Œ ๋ฐ์ดํ„ฐ ์‹ค์–ด๋ณด๋‚ด๊ธฐ

<button className="btn btn-danger mx-1" onClick={()=>{
    props.dispatch({ type : 'addItem', payload : { findId } });
    history.push('/cart');
}}>์ฃผ๋ฌธํ•˜๊ธฐ</button>
  • dispatch ํ•  ๋•Œ, ์•ˆ์— type ์™ธ์— payload ๋ผ๋Š” ํ•ญ๋ชฉ์„ ๋งŒ๋“ค์–ด์ฃผ๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ์ˆ˜ ์žˆ๋‹ค.
    (payload ๋ง๊ณ  ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•ด๋„ ๋˜์ง€๋งŒ, ๊ด€์Šต์ ์œผ๋กœ payload ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.)
  • ๋‚˜๋Š” ์—ฌ๊ธฐ์— ๊ธฐ์กด์— ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ์„ ์œ„ํ•ด ์‚ฌ์šฉํ–ˆ๋˜ findId ๋ฅผ ๋‹ด์•„ redux ๋กœ ์ „์†กํ•ด์ฃผ์—ˆ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  history.push('/cart') ๋ผ๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ „์†ก์ดํ›„์— ๋ฐ”๋กœ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์—ˆ๋‹ค.

 

4. ์ „์†กํ•œ ๋ฐ์ดํ„ฐ ์ถœ๋ ฅํ•˜๊ธฐ ๋ฐ ๊ฐ€์ ธ๋‹ค ์‚ฌ์šฉํ•˜๊ธฐ

  • redux ๋กœ ์ „์†กํ•œ ๋ฐ์ดํ„ฐ๋Š” reducer ํ•จ์ˆ˜ ์•ˆ์—์„œ action.payload ๋ผ๊ณ  ์ฝ˜์†”์— ์ถœ๋ ฅํ•ด๋ณด๋ฉด ์œ„์™€ ๊ฐ™์ด ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋‚˜์˜ ๊ฒฝ์šฐ 0๋ฒˆ ์ƒํ’ˆ์˜ ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ "์ฃผ๋ฌธํ•˜๊ธฐ" ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ payload ์— findId ๋ฅผ ์ „์†กํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ„์™€ ๊ฐ™์ด 0๋ฒˆ ์ƒํ’ˆ์˜ ๋‚ด์šฉ์ด ๋‹ด๊ธด findId ๊ฐ€ ์ถœ๋ ฅ๋˜์—ˆ๋‹ค.
  • ์ด์ œ ์ด๋ ‡๊ฒŒ ์ „์†ก๋ฐ›์€ ๋ฐ์ดํ„ฐ ๋‚ด์šฉ์—์„œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๋ฝ‘์•„๋‚ด๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ๋ฐ, ์ƒ์„ธ ํŽ˜์ด์ง€ ๋‚ด์šฉ์„ ๊ธฐ์กด defaultData ๋‚ด์— ์žˆ๋Š” object ์ž๋ฃŒํ˜•๊ณผ ํ†ต์ผ์‹œํ‚จ ํ›„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

// ๊ธฐ์กด์˜ ๊ฐ ๋ฐ์ดํ„ฐ๋Š” id, title, content, price ๋กœ ๊ตฌ์„ฑ
// findId ์— ๋‹ด๊ธด ๋ฐ์ดํ„ฐ๋Š” ์ด ํ˜•์‹์„ ์ง€๋‹˜

    {
      id : 0,
      title : "White and Black",
      content : "Born in France",
      price : 120000
    }
 
 
// ์ถ”๊ฐ€ํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” id, name, quan ์œผ๋กœ ๊ตฌ์„ฑ

{ id : 1, name : 'Red Knit', quan : 2 }
  • findId ๋ฅผ ํ†ตํ•ด ์ „์†ก๋ฐ›์€ ๋ฐ์ดํ„ฐ๋Š” id, title, content, price ๋กœ ๊ตฌ์„ฑ๋œ ๋ฐ˜๋ฉด, ์ €์žฅ๋˜์–ด์•ผํ•˜๋Š” ๋ฐ์ดํ„ฐ ํ˜•ํƒœ๋Š” id, name, quan ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด์•ผํ•œ๋‹ค.

 

// reducer ๋‚ด์˜ 'addItem' ์š”์ฒญ ๊ด€๋ จ if ๋ฌธ

if (action.type === 'addItem') {
    let item = action.payload.findId;
    let newState = [...state];
    newState.push({
        id : item.id,
        name : item.title,
        quan : 1
    })
    return newState;
}
  • ๋”ฐ๋ผ์„œ payload ๋ฅผ ํ†ตํ•ด ๋ฐ›์•„์˜จ findId ๋ฅผ item ์ด๋ผ๋Š” ๋ณ€์ˆ˜์— ์ €์žฅํ•˜์—ฌ, newState ์— push ํ•ด์ค„ ๋•Œ id ์—๋Š” item.id, name ์—๋Š” item.title, quan ์—๋Š” 1์„ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.
  • ๊ทธ๋ ‡๊ฒŒ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋œ ํ›„ return ๋œ newState ๋Š” Cart.js ํŒŒ์ผ์—์„œ props.data ๋กœ ๋ฐ›์•„ map() ํ•จ์ˆ˜๋ฅผ ๊ฑฐ์ณ ๋ธŒ๋ผ์šฐ์ €์˜ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€์— ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

 

728x90
๋ฐ˜์‘ํ˜•