React μƒνƒœ 관리 πŸ”

forhreverΒ·2023λ…„ 2μ›” 23일
0

πŸ“’ ν”„λ‘ νŠΈμ—”λ“œ κ°œλ°œμ—μ„œμ˜ μƒνƒœ 관리

μƒνƒœλž€ 무엇인가 ? UI에 λ™μ μœΌλ‘œ ν‘œν˜„λ  데이터λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

Side Effect ? ν•¨μˆ˜ λ˜λŠ” μ»΄ν¬λ„ŒνŠΈμ˜ μž…λ ₯ 외에도 ν•¨μˆ˜μ˜ 결과에 영ν–₯을 λ―ΈμΉ˜λŠ” μš”μΈμ„ λ§ν•©λ‹ˆλ‹€. λŒ€ν‘œμ μœΌλ‘œ λ„€νŠΈμ›Œν¬ μš”μ²­, API 호좜

둜컬 μƒνƒœ

  • νŠΉμ • μ»΄ν¬λ„ŒνŠΈ μ•ˆμ—μ„œλ§Œ κ΄€λ¦¬λ˜λŠ” μƒνƒœ
    => 보톡 μ»΄ν¬λ„ŒνŠΈ λ‚΄μ—μ„œλ§Œ 영ν–₯을 λΌμΉ˜λŠ” μƒνƒœ
    예) μž₯λ°”κ΅¬λ‹ˆλ₯Ό μ˜ˆμ‹œλ‘œ λ“ λ‹€λ©΄, 'μ„ νƒν•œ μˆ˜λŸ‰'이 둜컬 μƒνƒœμ΄λ‹€. μ›λž˜ 가격에 μƒνƒœλ₯Ό κ³±ν•΄ μ»΄ν¬λ„ŒνŠΈ 내에 ν‘œμ‹œλ˜λŠ” μ£Όλ¬Έ κΈˆμ•‘μ„ μ—…λ°μ΄νŠΈν•˜λ©΄ λœλ‹€.

μ „μ—­ μƒνƒœ

  • ν”„λ‘œλ•νŠΈ 전체 ν˜Ήμ€ μ—¬λŸ¬ 가지 μ»΄ν¬λ„ŒνŠΈκ°€ λ™μ‹œμ— κ΄€λ¦¬ν•˜λŠ” μƒνƒœ
    => λ‹€λ₯Έ μ»΄ν¬λ„ŒνŠΈμ™€ μƒνƒœλ₯Ό κ³΅μœ ν•˜κ³  영ν–₯을 λΌμΉ˜λŠ” μƒνƒœ
    예) μž₯λ°”κ΅¬λ‹ˆλ₯Ό μ˜ˆμ‹œλ‘œ λ“ λ‹€λ©΄, μž₯λ°”κ΅¬λ‹ˆμ— λ‹΄κΈ΄ λ¬Όν’ˆμ˜ 경우 μƒν’ˆ 선택 여뢀에 따라 총 μ£Όλ¬Έ κΈˆμ•‘μ„ μ—…λ°μ΄νŠΈ ν•΄μ•Όν•˜λ©°, μž₯λ°”κ΅¬λ‹ˆμ— λ‹΄κΈ΄ λ¬Όν’ˆμ€ κ·Έ 갯수 등을 λ‹€λ₯Έ μ»΄ν¬λ„ŒνŠΈμ— 전달해 μ£Όμ–΄μ•Ό ν•œλ‹€.

μ „μ—­ μƒνƒœμ—μ„œμ˜ 데이터 무결성

데이터 λ¬΄κ²°μ„±μ΄λž€ ? λ°μ΄ν„°μ˜ 정확성을 보μž₯ν•˜κΈ° μœ„ν•΄ λ°μ΄ν„°μ˜ λ³€κ²½μ΄λ‚˜ μˆ˜μ • μ‹œ μ œν•œμ„ 두어 μ•ˆμ •μ„±μ„ μ €ν•΄ν•˜λŠ” μš”μ†Œλ₯Ό 막고 데이터 μƒνƒœλ“€μ„ 항상 옳게 μœ μ§€ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

πŸ“’ Props Drilling

Props Drillingμ΄λž€? μƒμœ„ μ»΄ν¬λ„ŒνŠΈμ˜ stateλ₯Ό propsλ₯Ό 톡해 μ „λ‹¬ν•˜κ³ μž ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈλ₯Ό μ „λ‹¬ν•˜κΈ° μœ„ν•΄ κ·Έ μ‚¬μ΄λŠ” propsλ₯Ό μ „λ‹¬ν•˜λŠ” μš©λ„λ‘œλ§Œ μ“°μ΄λŠ” μ»΄ν¬λ„ŒνŠΈλ“€μ„ κ±°μΉ˜λ©΄μ„œ 데이터λ₯Ό μ „λ‹¬ν•˜λŠ” ν˜„μƒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

Props Drilling의 문제점

  • μ½”λ“œμ˜ 가독성이 맀우 λ‚˜λΉ μ§€κ²Œ λ©λ‹ˆλ‹€.
  • μ½”λ“œμ˜ μœ μ§€λ³΄μˆ˜ λ˜ν•œ νž˜λ“€μ–΄μ§€κ²Œ λ©λ‹ˆλ‹€.
  • state λ³€κ²½μ‹œ props 전달 κ³Όμ •μ—μ„œ λΆˆν•„μš”ν•˜κ²Œ κ΄€μ—¬λœ μ»΄ν¬λ„ŒνŠΈλ“€ λ˜ν•œ λ¦¬λ Œλ”λ§μ΄ λ°œμƒν•©λ‹ˆλ‹€. λ”°λΌμ„œ, μ›Ή μ„±λŠ₯에 μ•…μ˜ν–₯을 쀄 수 μžˆμŠ΅λ‹ˆλ‹€.

해결방법

  • μ»΄ν¬λ„ŒνŠΈμ™€ κ΄€λ ¨μžˆλŠ” stateλŠ” 될 수 있으면 κ°€κΉŒμ΄ μœ μ§€ν•˜λŠ” 방법
  • μƒνƒœκ΄€λ¦¬ 라이브러리λ₯Ό μ‚¬μš©ν•˜λŠ” 방법

μƒνƒœκ΄€λ¦¬ 라이브러리λ₯Ό μ“°λŠ” 이유

  • μ „μ—­μœΌλ‘œ κ΄€λ¦¬ν•˜λŠ” μ €μž₯μ†Œμ—μ„œ 직접 stateλ₯Ό κΊΌλ‚΄μ“Έ 수 있기 λ•Œλ¬Έμ— Props Drilling을 λ°©μ§€ν•˜κΈ°μ— 맀우 νš¨κ³Όμ μž…λ‹ˆλ‹€.
  • 라이브러리 μ’…λ₯˜λ‘œλŠ” Redux, Context api, Mobx, Recoil등이 μžˆμŠ΅λ‹ˆλ‹€.

과제1 - Cmarket Hooks πŸ›’

1. νŽ˜μ΄μ§€ μ „ν™˜

  • 루트 μ»΄ν¬λ„ŒνŠΈ : , , 둜 ꡬ뢄을 μ§€μ–΄μ€λ‹ˆλ‹€.
  • λ‚΄λΉ„κ²Œμ΄μ…˜ λ°” : SPA λ‚΄μ—μ„œ ν™”λ©΄ μ „ν™˜μ— 따라 URLλ₯Ό μ—…λ°μ΄νŠΈν•˜κΈ° μœ„ν•΄ μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

App.js

function App() {
  const [items, setItems] = useState(initialState.items);
  const [cartItems, setCartItems] = useState(initialState.cartItems);
  return (  
    <Router>
      <Nav cartItems = {cartItems}/>
      <Routes>
        <Route path="/" element={<ItemListContainer cartItems = {cartItems} setCartItems = {setCartItems} items={items} />} />
        <Route
          path="/shoppingcart"
          element={<ShoppingCart cartItems={cartItems} setCartItems = {setCartItems} items={items} />}
        />
      </Routes>
      <img
        id="logo_foot"
        src={`${process.env.PUBLIC_URL}/codestates-logo.png`}
        alt="logo_foot"
      />
    </Router>
  );
}
export default App;

Nav.js

function Nav({cartItems}) {
  return (
    <div id="nav-body">
      <span id="title">
        <img id="logo" src="../logo.png" alt="logo" />
        <span id="name">CMarket</span>
      </span>
      <div id="menu">
        <Link to="/">μƒν’ˆλ¦¬μŠ€νŠΈ</Link>
        <Link to="/shoppingcart">
          μž₯λ°”κ΅¬λ‹ˆ<span id="nav-item-counter">{cartItems.length}</span>  // cartItems.length으둜 μˆ˜λŸ‰ λ°”κΏ”μ£ΌκΈ°
        </Link>
      </div>
    </div>
  );
}
export default Nav;

2. μž₯λ°”κ΅¬λ‹ˆμ— μΆ”κ°€ 및 μƒν’ˆ 개수 μ—…λ°μ΄νŠΈ

  • 메인 ν™”λ©΄μ—μ„œ [μž₯λ°”κ΅¬λ‹ˆ λ‹΄κΈ°] λ²„νŠΌμ„ λˆ„λ₯Έ ν›„, μž₯λ°”κ΅¬λ‹ˆ νŽ˜μ΄μ§€λ‘œ μ΄λ™ν•˜λ©΄ μƒν’ˆμ΄ λ‹΄κ²¨μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.
  • μž₯λ°”κ΅¬λ‹ˆ νŽ˜μ΄μ§€μ—μ„œ μž₯λ°”κ΅¬λ‹ˆμ— λ‹΄κΈ΄ 각 μ•„μ΄ν…œμ˜ 개수λ₯Ό λ³€κ²½ν•  수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.
  • λ‚΄λΉ„κ²Œμ΄μ…˜ 바에 μƒν’ˆ κ°œμˆ˜κ°€ μ¦‰μ‹œ ν‘œμ‹œλ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

ItemListContainer.js

function ItemListContainer({ cartItems, setCartItems, items }) {
  const handleClick = (e, index) => {
    let addNew = {};
    addNew.itemId = index;
    addNew.quantity = 1;
    if(cartItems.length === 0) setCartItems([...cartItems, addNew])
    for(let i = 0; i < cartItems.length; i++) {
      if(cartItems[i].itemId === index) { // μž₯λ°”κ΅¬λ‹ˆμ— μ—†λŠ” μ•„μ΄ν…œμ€ μΆ”κ°€
        setCartItems([...cartItems])
        cartItems[i].quantity++
      } else {  // μž₯λ°”κ΅¬λ‹ˆμ— μžˆλŠ” μ•„μ΄ν…œμ΄λ©΄ μˆ˜λŸ‰λ§Œ μΆ”κ°€
        setCartItems([...cartItems, addNew])
      }
    }
   }
  return (
    <div id="item-list-container">
      <div id="item-list-body">
        <div id="item-list-title">μ“Έλͺ¨μ—†λŠ” μ„ λ¬Ό λͺ¨μŒ</div>
        {items.map((item, idx) => <Item item={item} key={idx} handleClick={handleClick} />)}
      </div>
    </div>
  );
}
export default ItemListContainer;


ShoppingCart.js

const handleQuantityChange = (quantity, itemId) => {
    const newCart = [...cartItems];
    const idFilter = cartItems.findIndex(el => el.itemId === itemId); // newCart[인덱슀번호]의 μˆ˜λŸ‰ = λ°›μ•„μ˜¨ μˆ˜λŸ‰ 으둜 λ°”κΏ”μ€€λ‹€.
    newCart[idFilter].quantity = quantity;
    setCartItems(newCart);
  }

3. μž₯λ°”κ΅¬λ‹ˆλ‘œλΆ€ν„° 제거

  • μž₯λ°”κ΅¬λ‹ˆ νŽ˜μ΄μ§€μ—μ„œ [μ‚­μ œ] λ²„νŠΌμ„ λˆ„λ₯Έ ν›„, ν•΄λ‹Ή μƒν’ˆμ΄ λͺ©λ‘μ—μ„œ μ‚­μ œλ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.
  • λ‚΄λΉ„κ²Œμ΄μ…˜ 바에 μƒν’ˆ κ°œμˆ˜κ°€ μ¦‰μ‹œ ν‘œμ‹œλ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

ShoppingCart.js

  const handleDelete = (itemId) => {
    setCheckedItems(checkedItems.filter((el) => el.itemId !== itemId))
    setCartItems(cartItems.filter(el => el.itemId !== itemId))
  } 
  // filter을 μ‚¬μš©ν•˜μ—¬ el.itemId와 클릭된 itemId값을 λΉ„κ΅ν•΄μ„œ 같은 κ°’λ§Œ μ‚­μ œλ˜λ„λ‘ 


였늘 ν•™μŠ΅μ„ 마치고 λ‚˜μ„œ, πŸ“–

과제 μ½”λ“œ μž‘μ„±ν•˜λŠ” 뢀뢄은 μΈν„°λ„·μ˜ νž˜μ„ λΉŒλ Έλ‹€. 혼자 μž‘μ„±ν•΄λ³΄κ³  μ‹Άμ—ˆμ§€λ§Œ λŒ€μ²΄ 뭘 μž‘μ„±ν•΄μ•Όν•˜λŠ”κ±΄μ§€ λ§‰λ§‰ν•œ μƒνƒœμ˜€λ‹€. μ œμΆœν•˜λŠ” κ³Όμ œκ°€ μ•„λ‹ˆλΌ κ·Έλ‚˜λ§ˆ μ—¬μœ λ‘­κ²Œ 더 곡뢀 ν•  수 μžˆλŠ” 것 κ°™λ‹€. 내일 λ¦¬λ•μŠ€λ₯Ό λ°°μš°λŠ”λ° λ¦¬λ•μŠ€ 뢀뢄을 잘 κΈ°μ–΅ν•˜κ³  μ΄ν•΄ν•˜λ©΄ 될 것 κ°™λ‹€. 개인적으둜 λ§Œλ“€κ³  μžˆλŠ” λ―Έλ‹ˆ ν”„λ‘œμ νŠΈμ—λ„ λ¦¬λ•μŠ€λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμ–΄ 배우면 λ―Έλ‹ˆ ν”„λ‘œμ νŠΈμ—λ„ 도움이 될 것 κ°™λ‹€. λ¦¬μ•‘νŠΈλŠ” 맀번 μ–΄λ ΅κ³  μƒˆλ‘­λ‹€. λ¦¬μ•‘νŠΈ 쉽지 μ•Šλ‹€.. 만만치 μ•Šμ€ 녀석이닀..

profile
개발자 μ„±μž₯ 계단 μ˜¬λΌκ°€κΈ°

0개의 λŒ“κΈ€