[React] 아주 간단한 커피주문 계산 (2)

HYEJIN·2022년 8월 15일
0
post-custom-banner

변경전
MenuList 같은 컴포넌트가 중복되는 것을 알 수 있다.
지금은 데이터가 몇개 되지 않지만 이것이 백개만 넘어가더라도 일일히 다 수정을 해야하는 번거로움도 있다.

return (
    <>
      <MenuList price="4100" menu="아메리카노" handleClick={handleClick} />
      <MenuList price="4600" menu="카페라떼" handleClick={handleClick} />
      <MenuList price="5100" menu="캐러멜 마키아토" handleClick={handleClick} />
      <button onClick={handleClickTotal}>총 가격 </button> : {payMoney}
      <p>남는 돈: {change} </p>
    </>
  );


변경 후
coffee라는 객체를 가진 배열이 있다고 가정하고,
map함수를 활용하여 MenuList 컴포넌트를 coffee라는 객체에 따라 유동적으로 사용할 수 있도록 변경했다.

//data 
const coffee = [
  {
    menu: "아메리카노",
    price: 4100,
    count: 0,
  },
  {
    menu: "카페라떼",
    price: 4600,
    count: 0,
  },
  {
    menu: "캬라멜 마끼아또",
    price: 5100,
    count: 0,
  },
];
// 
return (
    <>
      {coffee &&
        coffee.map((item) => (
          <MenuList
            price={item.price}
            menu={item.menu}
            handleClick={handleClick}
          />
        ))}
      <button onClick={handleClickTotal}>총 가격 </button> : {payMoney}
      <p>남는 돈: {change} </p>
    </>
  );


전체코드

import React, { useState, useEffect } from "react";

function App() {
  return (
    <div className="App">
      <Menu />
    </div>
  );
}
//data
const coffee = [
  {
    menu: "아메리카노",
    price: 4100,
    count: 0,
  },
  {
    menu: "카페라떼",
    price: 4600,
    count: 0,
  },
  {
    menu: "캬라멜 마끼아또",
    price: 5100,
    count: 0,
  },
];

//  -----------------------------함수형 컴포넌트 분리
const Menu = () => {
  const MONEY = 50000; // 지정한 회비

  const [data, setData] = useState([]);
  const [payMoney, setPayMoney] = useState(0);
  const [change, setChange] = useState(0);

  const handleClickTotal = (e) => {
    //총 가격 계산
    const total = data.reduce((pre, cur) => {
      return pre + cur.price * cur.count;
    }, 0);

    //가격에 따라서 총 금액과 남는돈 set
    setPayMoney(total);
    setChange(MONEY - total);
  };

  //데이터 잘 보이는지 보려는 용도
  useEffect(() => {
    console.log("Menu useEffect", data);
  }, [data]);

  const handleClick = (pass) => {
    //console.log("pass data:", pass);

    const newData = [...data];
    const exist = newData.find((item) => pass.menu === item.menu);

    //같은 데이터가 존재하지 않는다면 넣어주고
    if (!exist) {
      newData.push(pass);
    }
    //같은 데이터가 존재한다면 count값만 갱신
    else {
      newData.forEach((item, index) => {
        if (item.menu === pass.menu) {
          newData[index].count = pass.count;
        }
      });
    }
    setData(newData);
  };

  return (
    <>
      {coffee &&
        coffee.map((item) => (
          <MenuList
            price={item.price}
            menu={item.menu}
            handleClick={handleClick}
          />
        ))}
      <button onClick={handleClickTotal}>총 가격 </button> : {payMoney}
      <p>남는 돈: {change} </p>
    </>
  );
};

const MenuList = ({ price, menu, handleClick }) => {
  const [count, setCount] = useState(0);

  //useEffect로 변경하여 부모컴포넌트에 데이터를 전달
  useEffect(() => {
    handleClick({ price, menu, count });
  }, [count]);

  //이것도 왜 2번호출되지 ?
  // useEffect(() => {
  //   console.log("useEffect : ");
  // }, []);

  const handleClickAdd = () => setCount(count + 1);

  const handleClickDelete = () =>
    setCount((current) => (current > 0 ? current - 1 : 0));

  return (
    <p>
      <span>{`${price}${menu}: `}</span>
      <span>{`${count}`}</span>
      <button onClick={handleClickAdd}>추가</button>
      <button onClick={handleClickDelete}>감소</button>
    </p>
  );
};

export default App;
post-custom-banner

0개의 댓글