React

[TIL/React] 2023/10/10

CartPage ์‹œ์ž‘ ๐ŸŸขdetail page์— ์žˆ๋Š” ๋‚ด์šฉ์ด๋‹ค. ๋ฐ”๋กœ๊ตฌ๋งค๋ฅผ ํด๋ฆญํ•˜๋ฉด ๊ฐ€์žฅ ๋จผ์ € if ๋ฌธ์„ ํ†ตํ•ด ๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•œ๋‹ค. ๋กœ๊ทธ์ธ์ด ๋˜์–ด ์žˆ์ง€ ์•Š์€ ์ƒํƒœ๋ผ๋ฉด ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ณ , ๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋œ ์ƒํƒœ๋ผ๋ฉด ์‡ผํ•‘์นดํŠธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•œ๋‹ค. ์ด๋•Œ ์ด๋™์— ์•ž์„œ

2023๋…„ 10์›” 10์ผ2min read

CartPage ์‹œ์ž‘ ๐ŸŸข

detail page์— ์žˆ๋Š” ๋‚ด์šฉ์ด๋‹ค. ๋ฐ”๋กœ๊ตฌ๋งค๋ฅผ ํด๋ฆญํ•˜๋ฉด ๊ฐ€์žฅ ๋จผ์ € if ๋ฌธ์„ ํ†ตํ•ด ๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•œ๋‹ค. ๋กœ๊ทธ์ธ์ด ๋˜์–ด ์žˆ์ง€ ์•Š์€ ์ƒํƒœ๋ผ๋ฉด ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ณ , ๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋œ ์ƒํƒœ๋ผ๋ฉด ์‡ผํ•‘์นดํŠธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•œ๋‹ค. ์ด๋•Œ ์ด๋™์— ์•ž์„œ dispatch๋ฅผ ํ†ตํ•ด DetailData์— category key๋ฅผ ์ถ”๊ฐ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ getCartData๋ผ๋Š” ์•ก์…˜ ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๊ฒŒ ๋œ๋‹ค.

CartPage ๐ŸŸข

์˜์—ญ์€ ํฌ๊ฒŒ ์„ธ ํŒŒํŠธ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. (์ œ๋ชฉ, ๋ฐ์ดํ„ฐ, ์ดํ•ฉ)์ด ๋ฐ”๋กœ ๊ทธ๊ฒƒ์ด๋‹ค. dataArea์™€ totalDataArea๊ฐ€ componentWrapper ๋‚ด๋ถ€์—์„œ 3๋Œ€ 1์˜ ๋น„์œจ๋กœ ์˜์—ญ์„ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ๋‹ค.

dataArea๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑ๋œ๋‹ค.

์ƒํ’ˆ์ •๋ณด, ์ˆ˜๋Ÿ‰, ๊ฐ€๊ฒฉ์ด ๊ธฐ์žฌ๋œ ์ฒซ ๋ฒˆ์งธ ํ–‰์˜ ๋น„์œจ๊ณผ ๋™์ผํ•˜๊ฒŒ, ํ•˜๋‹จ์— ์ถ”๊ฐ€๋  ๋ฐ•์Šค์˜ ๋น„์œจ์„ ์กฐ์ •ํ•œ ๋ชจ์Šต์ด๋‹ค. ์„ธ ์˜์—ญ์—์„œ๋Š” useSelector๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ์ ์ ˆํžˆ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ๋‹ค.

์œ„ ์ฝ”๋“œ๋Š” ํ˜„์žฌ๋กœ์„œ ๊ฐ€์žฅ ๋ฌธ์ œ๊ฐ€ ๋งŽ์€ ๋ถ€๋ถ„์ด๋‹ค. ์ˆ˜๋Ÿ‰์— ๋”ฐ๋ฅธ ๊ฐ€๊ฒฉ์˜ ์ดํ•ฉ์„ ๋ณด์—ฌ์ค˜์•ผ ํ•œ๋‹ค.

code
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import styled from "styled-components";
import { calElemTotalPrice } from "../../modules/cartSlice";
import { shoppingData } from "../../data/ShoppingCategory_Pork";
import { useLocation } from "react-router-dom";
import { useParams } from "react-router-dom";
import { splitPrice } from "../../utils/commonModule";

const CounterContainer = styled.div`
  display: flex;
  align-items: center;
`;

const Button = styled.button`
  padding: 10px 20px;
  font-size: 1.5em;
`;

const Display = styled.div`
  padding: 10px;
  font-size: 1.5em;
  margin: 0 20px;
`;

const Counter = () => {
  const [count, setCount] = useState(1);
  const { id } = useParams();
  const dispatch = useDispatch();
  const location = useLocation();
  const category = location?.state;
  const MapData = shoppingData[category];
  const DetailData = MapData?.find((elem) => elem?.id === id);
  const purePrice = splitPrice(DetailData?.price);

  const elemTotalPrice = purePrice * (count + 1);

  const updateCount = (st) => {
    dispatch(calElemTotalPrice(st));
  };

  const handleIncrement = () => {
    setCount((prevCount) => prevCount + 1);
  };

  const handleDecrement = () => {
    if (count > 1) {
      setCount((prevCount) => prevCount - 1);
    }
  };

  return (
    <CounterContainer>
      <Button
        onClick={() => {
          updateCount(elemTotalPrice);
          handleDecrement();
        }}
      >
        -
      </Button>
      <Display>{count}</Display>
      <Button
        onClick={() => {
          updateCount(elemTotalPrice);
          handleIncrement();
        }}
      >
        +
      </Button>
    </CounterContainer>
  );
};

export default Counter;

์š”์†Œ์˜ total price๋ฅผ ๊ตฌํ•ด์„œ updateCount๋ผ๋Š” ์•ก์…˜ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๊ณ , ํ•ด๋‹น ๊ฐ’์œผ๋กœ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค๋Š” ๋…ผ๋ฆฌ์ด๋‹ค. ๋ฌธ์ œ๋Š” category๋ณ„๋กœ ์ ‘๊ทผํ•˜์ง€ ์•Š์•„์„œ ๋‚˜๋จธ์ง€ ์š”์†Œ๋“ค์˜ ๊ฐ€๊ฒฉ์ด ๋™์ผํ•˜๊ฒŒ ๋‚˜ํƒ€๋‚œ๋‹ค. ๋ฌด์Šจ ๋ง์ผ๊นŒ?

๊ทธ์ € ์—‰๋ง์ด๋ผ๋Š” ์†Œ๋ฆฌ๋‹ค. ๋‚ด์ผ์€ ์ด ๋ถ€๋ถ„๋ถ€ํ„ฐ ํ•ด๊ฒฐํ•˜๊ฒ ๋‹ค.

More to read

Amazon VPC

Amazon VPC Architecture ์ดํ•ดํ•˜๊ธฐ

์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ๊ธฐํšํ•˜๋ฉฐ, ๊ฐœ๋ฐœ์—์„œ ๋ฌด์—‡์„ ๊ฐ€์žฅ ๋จผ์ € ๊ณ ๋ฏผํ•ด์•ผ ํ•˜๋Š”์ง€ ๋‹ค์‹œ ๋Œ์•„๋ณด๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.ํ•œ๋•Œ๋Š” ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ๋ชจ๋“  ์„ค๊ณ„์˜ ์ถœ๋ฐœ์ ์ด๋ผ๊ณ  ๋ฏฟ์—ˆ์Šต๋‹ˆ๋‹ค. ์œ ์ €๊ฐ€ ๋ฌด์—‡์„ ๋ณด๊ณ , ์–ด๋–ค ํ๋ฆ„์—์„œ ๋จธ๋ฌด๋ฅด๊ณ  ์ดํƒˆํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ดํ•ด ์—†์ด ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ ๋‹ค๋Š” ๊ฑด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๊ธฐ

'์›์‚ฌ์ดํŠธ'

ํ”„๋ก ํŠธ์—”๋“œ ๊ด€์ ์œผ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ดํ•ดํ•˜๊ธฐ

์˜ค๋žœ๋งŒ์— ๋ฐฉ๋ฒ•๋ก ์— ๊ด€ํ•œ ๊ธ€์„ ์“ฐ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ตœ๊ทผ ์ƒํ™ฉ์€ ์ด๋ ‡์Šต๋‹ˆ๋‹ค. SSAFY์—์„œ๋Š” ํ•˜๋ฃจ์— ์—„์ฒญ๋‚œ ์–‘์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ๋“ค์„ ๊ณผ์ œ๋กœ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ๊ณผ์ •์—์„œ, '๊ตฌํ˜„๋ ฅ'์ด ๋งค์šฐ ๋–จ์–ด์ง„๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์™„์ „ํžˆ ์–ด๋ ค์šด ๋ฌธ์ œ๋ผ๋ฉด '์•„์‰ฌ์›€'์ด๋ผ๋Š” ๊ฐ์ •์กฐ์ฐจ ๋А๋ผ์ง€

Subnet

VPC ์„ค๊ณ„์˜ ์‹œ์ž‘: IP์™€ Subnet

๋ฐ˜๋ณต๋˜๋Š” ๋ฃจํ‹ด ์†์—์„œ ์–ป์€ ์•ˆ์ •๊ฐ์„ ๋ฐœํŒ ์‚ผ์•„, ์ด์ œ๋Š” ๊ธฐ์ˆ ์  ์ŠคํŽ™ํŠธ๋Ÿผ์„ ๋„“ํžˆ๊ธฐ ์œ„ํ•œ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ์— ์ฐฉ์ˆ˜ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์˜ ๋ชฉํ‘œ๋Š” ๋‹จ์ˆœํ•œ ํฌํŠธํด๋ฆฌ์˜ค ๊ตฌ์ถ•์„ ๋„˜์–ด, ์‹ค์ œ ์„œ๋น„์Šค ์ˆ˜์ค€์˜ ๋ธ”๋กœ๊ทธ ์‹œ์Šคํ…œ ๊ตฌํ˜„๊ณผ ๋‹ค๊ตญ์–ด ์ฒ˜๋ฆฌ ์ ์šฉ ๋“ฑ ์‹ค๋ฌด์— ๊ฐ€๊นŒ์šด ์—ญ๋Ÿ‰์„ ํ•œ ๋‹จ๊ณ„