[React]cmarket : 장바구니 기능구현

KoEunseo·2022년 8월 31일
0

코드스테이츠

목록 보기
31/45

파일구조


props를 어떻게 내려주어야할지 가늠하기 위해 먼저 파일구조를 그려보면 좋다. 물론 나는 열심히 하다가 중간에 피그마를 켰음...^^

app.js

function App() {
  // 아이템, 카트에 담긴 아이템에 대한 상태 관리 함수 생성
  const [items, setItems] = useState(initState.cartItems);
  const [cartItems, setCartItems] = useState(initState.cartItems);
  return (
    <div> //실제로는 라우터를 사용해 페이지를 나누어주었음.
      <ItemListContain 
        //props로 하위 컴포넌트에 전달
		items={items}
        cartItems={cartItems}
        setCartItems={setCartItems} />
      <CartContain 
        cartItems={cartItems}
        setCartItems={setCartItems} />
    </div>
  )
}

ItemListContain.js

상품을 장바구니에 추가하는 기능을 구현함. 페어분이랑은.. setCartItem을 이용해 다른 함수를 만들어서 그 함수를 전달했었다. 그럴필요가 없었는데...; 상태변경함수를 그냥 props로 넘겼을때 분명 오류가 떠서 상태변경함수가 아니라 그 함수를 이용한 함수를 부모컴포넌트에서 작성하고 보내야한다고 하셨는데 아니었던걸로.. 그래두 기능은 작동이 됐고 덕분에 확실히 알게됐다ㅋㅋㅋㅋ!! 그래 뭔가 이상했어

function ItemListContain( //props 넘겨받음
{ items, cartItems, setCartItems }) {
  const clickHandle = (itemId) => {
    //장바구니에 있는지 확인
    if(!cartItems.find(el => el.itemId === itemId){
       //장바구니에 추가
      setCartItems([...cartItems, { itemId: itemId, quantity: 1 }])   
    }
  }
  return (
    <div>
      {items.map(
        (item, i) => <Item 
                       item={item} 
                       key={i} 
                       clickHandle={clickHandle} />)}
    </div>
  )
}

CartContain.js

상품개수 핸들링하는 컴포넌트를 만들때 quantity 상태를 관리해야겠다는 생각이 들어서 useState를 사용해 [quantities, setQuantity] = useState(1) 을 만들었었다.. 근데 굳이 양에 대한 상태를 만들 게 아니라 setCartItems를 이용하면 된다.

  const [quantities, setQuantity] = useState(1)
  const quantityChange = (quantity, itemId) => {
    //itemId 기준으로 분기
    const itemQuantity = cartItems.filter(el => el.itemId === itemId);
    itemQuantity[0].quantity = quantity;
    setQuantity(itemQuantity[0].quantity);
  }
function CartContain({ items, cartItems, setCartItems }){
  const [checkedItems, setCheckedItems] = useState(cartItems.map(el => el.itemId))
  const checkChange = (checkde, id) => { //체크여부 확인하는 함수
    if(checked) {setCheckedItems([...checkedItems, id])}
    else {setCheckedItems(checkedItems.filter(el => el !== id))}
  }
  const allCheck = (checked) => {
    //올체크를 클릭하면 카트에 담긴 아이템들을 다 체크한다.
    if(checked) {setCheckedItems(cartItems.map((el) => el.itemId));}
    else {setCheckedItems([])}
  }
  //장바구니에서 상품 개수가 변경되면 상태 반영해주기
  const quantityChange = (quantity, itemId) => {
    setCartItems(
      cartITems.map(item => {
        item.itemId === itemId ? { itemId, quantity } : item;)
      })
    )
  }
  const deleteItem = (itemId) => {
    //체크해제할때 실행되는 함수
    setCheckedItems(checkedItems.filter((el) => el !== itemId))
    //장바구니 상품 삭제할때 실행되는 함수
    setCartItems(cartItems.filter(el => el.itemId !== itemId))
  }
  
  return (
    <div>
      <input type = {checkbox} //allcheck
        checked = {checkedItems.length === cartItems.length ? true : false }
        onChange = {e => allCheck(e.target.checked)}/>
      <div>
        { !cartITems.length ? //카트에 아이템이 없으면
          (<div> No Item </div>) 
        : ( //아이템 있으면
          <div cartItems.map((item, i) => {
            const quantity = cartItems.filter(el => el.itemId === item.id)[0].quantity
            return <CartItem
                     key={i}
                  checkChange={checkChange}
                  quantityChange={quantityChange}
                  deleteItem={deleteItem}
                  item={item}
                  checkedItems={checkedItems}
                  quantity={quantity}> //위에서 필터링해준 quantity가 여기 들어옴
            })
            ></div>
        )}
      </div>
    </div>
  )
}

그 외에 구현이 이미 되어있던 파일들

  • CartItem.js
    • input에서 최소값을 1개로 지정해두었다. min={1}
    • onChange함수를 사용하고있음. quantityChange! 이 함수를 부모컴포넌트에서 만들어야했다.
  • Nav.js
    • 장바구니의 개수를 가져와야하기때문에 items를 props로 가져옴. items.length 씀
profile
주니어 플러터 개발자의 고군분투기

0개의 댓글