[TIL/React] 2023/10/05
๋ฐ์ํ ๐ขpx(ํฝ์ )๊ณผ ๊ฐ์ ๊ณ ์ ๋จ์๋ฅผ ์ฐ๋ฉด ์์ ๊ฐ์ด ์ฒ์ฐธํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค. ์ฝ๋๋ฅผ ์์ ํ๋ค.์์ ํ ๋ชจ์ต ๐ข์ฝ๋์ ๋ํ ์ค๋ช ์ด ํ์ํ๋ฐ, ์ค๋์ ๋์ ํ ํ์ด ๋์ง ์๋๋ค. handleDirectClick ํจ์๋ฅผ ํตํด, ๋ก๊ทธ์ธ์ด ๋์ด ์์ง ์๋ค๋ฉด logi
๋ฐ์ํ ๐ข

px(ํฝ์ )๊ณผ ๊ฐ์ ๊ณ ์ ๋จ์๋ฅผ ์ฐ๋ฉด ์์ ๊ฐ์ด ์ฒ์ฐธํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค. ์ฝ๋๋ฅผ ์์ ํ๋ค.
import React from "react";
import { useParams, useLocation, useNavigate } from "react-router-dom";
import styled from "@emotion/styled";
import { shoppingData } from "../data/ShoppingCategory_Pork";
import ComponentWrapper from "../components/common/ComponentWrapper";
import { useSelector } from "react-redux";
const ProductDetailPageBackgroundStyle = styled.div`
background-color: #181818;
width: 100%;
/* height: 100vh; */
`;
const AllContentWrapper = styled.div`
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
/* flex-grow: 1; */
/* background-color: white; */
@media (max-width: 900px) {
flex-wrap: wrap;
column-gap: 20px;
}
`;
const ProductDetailPageImgWrapper = styled.div`
/* height: 70%;
width: 50%; */
display: flex;
justify-content: center;
align-items: center;
background-color: white;
`;
const ProductImg = styled.img`
width: 80%;
height: 80%;
`;
const ProductDetailPageInfoWrapper = styled.div`
/* width: 50%;
height: 70%; */
display: flex;
flex-direction: column;
background-color: blue;
`;
const ProductDetailPageInfoDataWrapper = styled.div`
height: 30%;
`;
const InfoDataTitle = styled.p`
font-size: 30px;
color: white;
font-weight: bolder;
`;
const InfoDataEtc = styled.p`
font-size: 20px;
color: white;
font-weight: bolder;
`;
const OptionWrapper = styled.div`
display: flex;
align-items: center;
column-gap: 20px;
height: 20%;
color: white;
`;
const AmountWrapper = styled.div`
display: flex;
align-items: center;
column-gap: 20px;
height: 20%;
color: white;
`;
const ButtonWrapper = styled.div`
width: 100%;
background-color: orange;
display: flex;
height: 30%;
justify-content: space-evenly;
align-items: center;
`;
const ProductDetailPage = () => {
const navigate = useNavigate();
const { id } = useParams();
const location = useLocation();
const category = location?.state;
const check = useSelector((state) => state.auth);
console.log(check);
const handleDirectClick = () => {
if (check.isAuthenticated) {
console.log("๊ฒฐ์ ํ๋ฉด์ผ๋ก");
} else {
navigate("/login");
}
};
const MapData = shoppingData[category];
const DetailData = MapData.find((elem) => elem?.id === id);
const ImgSrc = DetailData.image;
console.log(location);
console.log(DetailData);
console.log(ImgSrc);
return (
<>
<ProductDetailPageBackgroundStyle>
{/* */}
<ComponentWrapper style={{ height: "100%" }}>
<AllContentWrapper>
{/* image area */}
<ProductDetailPageImgWrapper>
<ProductImg src={ImgSrc} />
</ProductDetailPageImgWrapper>
{/* info area */}
<ProductDetailPageInfoWrapper>
<ProductDetailPageInfoDataWrapper>
<InfoDataTitle>{DetailData?.subtitle}</InfoDataTitle>
<InfoDataEtc>
{DetailData?.price} ({DetailData?.weight})
</InfoDataEtc>
<p></p>
</ProductDetailPageInfoDataWrapper>
<OptionWrapper>
<span style={{ color: "white", fontWeight: "bolder" }}>
์ต์
</span>
<div style={{ border: "2px solid orange" }}>
fdsagfagfdagfdgfda
</div>
</OptionWrapper>
<AmountWrapper>
<span style={{ color: "white", fontWeight: "bolder" }}>
์๋
</span>
<div style={{ border: "2px solid orange" }}>
fdsagfagfdagfdgfda
</div>
</AmountWrapper>
<ButtonWrapper>
<button
style={{
backgroundColor: "#7f7776",
color: "white",
width: "200px",
height: "60px",
border: "none",
}}
onClick={handleDirectClick}
>
๋ฐ๋ก๊ตฌ๋งค
</button>
<button
style={{
backgroundColor: "#c50f22",
color: "white",
width: "200px",
height: "60px",
border: "none",
}}
>
์ฅ๋ฐ๊ตฌ๋
</button>
</ButtonWrapper>
</ProductDetailPageInfoWrapper>
</AllContentWrapper>
</ComponentWrapper>
</ProductDetailPageBackgroundStyle>
</>
);
};
export default ProductDetailPage;
์์ ํ ๋ชจ์ต ๐ข


์ฝ๋์ ๋ํ ์ค๋ช ์ด ํ์ํ๋ฐ, ์ค๋์ ๋์ ํ ํ์ด ๋์ง ์๋๋ค. handleDirectClick ํจ์๋ฅผ ํตํด, ๋ก๊ทธ์ธ์ด ๋์ด ์์ง ์๋ค๋ฉด login page๋ก ์ด๋ํ๋๋ก ์ค์ ํ๋ค.
ํ๊ณ ๐ข
1) ์๋์ ์ธ ๋จ์๋ฅผ ์จ์ผ ๋ด๋ณ์ ๋ฉดํ ์ ์๋ค๋ ์ ์ ๊นจ๋ฌ์๋ค. 2) 1๋ฒ์ ์ฌ์ค ์ด๋ฏธ ์๊ณ ์์๋๋ฐ, container ๋จ์๋ก ์๋ ๋จ์๋ฅผ ์จ์ผ ํจ์ ๋ค์๊ธ ๊นจ๋ฌ์๋ค. 3) ๋ฌธ์ ๋ 2๋ฒ์์ ๋๋ ์ ์ด ๋ง๋ ๊ฒ์ธ์ง ์๋ฌธ์ด๋ค. 4) ๊ทธ๋๋ ๋๊ฐ ๊ตฌ์กฐ๋ฅผ ์ก์์ผ๋, ์ฅ๋ฐ๊ตฌ๋๋ฅผ ์ฌ์ฌ ๋ง๋ค๋๋ก ํ์.
More to read
ํ๋ก ํธ์๋์ ๋ฐฑ์๋ ์ฌ์ด
HTTP ์ํ ์ฝ๋๋ ํ๋ก ํธ์๋์์ ๋ฐฑ์๋๋ก ๋ณด๋๋ ์์ฒญ์ ์ํ ๊ฒฐ๊ณผ๋ฅผ ์๋ฏธํ๋ ์ผ์ข ์ ์ฝ์์ด๋ฉฐ, API๋ฅผ ๊ตฌ์ฑํ๋ ํต์ฌ ์์ ์ค ํ๋์ ๋๋ค. ์ํ ์ฝ๋์ ๊ด๋ จํ์ฌ, ๋ฐฑ์๋๋ ์ ๋ชจ๋ฅด๋ ํ๋ก ํธ์๋์ ์ฌํ ์ฌ์ ์ด ์์ต๋๋ค.์๋๋ ์์ฒญ์ด ์คํจํ์์๋, ๋ฐฑ์๋์์ ์ํ ์ฝ๋
JWTํ ํฐ ๊ด๋ฆฌ ๋ฐฉ์ ํบ์๋ณด๊ธฐ
0. ๋ค์ด๊ฐ๋ฉฐ ๐ฏ ์๋น์ค์ ์ ๊ทผํ๋ ค๋ ์ฌ์ฉ์๊ฐ ๋๊ตฌ์ธ์ง ํ์ธํ๋ ๊ณผ์ ์ ์ฌ์ฉ์ ์ธ์ฆ์ด๋ผ๊ณ ํฉ๋๋ค. ์ธ์ฆ๋ ์ฌ์ฉ์์๊ฒ ์ฃผ์ด์ง ๊ถํ์ ํ์ธํ๋ ์์ ์ ์ธ๊ฐ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. ์ด๋ฒ ๊ธ์์๋ ์ธ๊ฐ๋ ๋ค๋ฃจ์ง ์์ต๋๋ค. ์ฌ์ฉ์ ์ธ์ฆ์๋ ๋ง์ ๋ฐฉ์์ด ์์ง๋ง, ์ค๋์ ์ธ์ ์ธ์ฆ ๋ฐฉ
A2AA2A / MCP ๋ฉํฐ ์์ด์ ํธ ์ค์ผ์คํธ๋ ์ด์
0. ๋ค์ด๊ฐ๋ฉฐ โ๏ธ Google for Developers์, ๋ ์คํ ๋ ๊ณต๊ธ๋ง ์๋๋ฆฌ์ค๋ก ์ฎ์ 6๋ ํ๋กํ ์ฝ(MCP, A2A, UCP, AP2, A2UI, AG-UI)์ ๋ํ ๊ฐ์ด๋๊ฐ ๊ฒ์๋ ์ดํ, MCP์ A2A๋ถํฐ ๊ตฌํํด ๋ณด๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ค์์ต๋