์ฌ๊ธฐ ์์
ํ ๋ db๋ฅผ ์์ ์ด ์ข ๋ง์ด ๋ค์ด๊ฐ
- ์ฒ์์ ์ค๊ณํ DB๋ ์ฅ๋ฐ๊ตฌ๋์ ์๋ ๋ชจ๋ ํญ๋ชฉ๋ค์ ๊ฒฐ์ ํ๊ธฐ ํ์ด์ง์์ ๋ค ๊ฐ์ ธ์์์.
- ๊ทผ๋ฐ ๊ทธ๋ ๊ฒ ํ๋ค๋ณด๋ ์ฅ๋ฐ๊ตฌ๋์ ๋ฃ์ง์๊ณ ๋ฐ๋ก ๊ฒฐ์ ํ๊ธฐ๋ฅผ ํด๋ฆญํ ๊ฒฝ์ฐ์๋ ์ฅ๋ฐ๊ตฌ๋์ ์๋ ์ํ + ๊ฒฐ์ ํ๊ธฐ ํด๋ฆญํ ์ํ์ด ๊ฒฐ์ ํ๊ธฐ ํ์ด์ง๋ก ๋์ด๊ฐ๊ฒ ๋จ.
- ๊ทธ๋์ ์ด ๋จ๊ณ๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํด์ DB์ ์์ ์ ํ๊ธฐ๋ก ํจ
- ์ฃผ๋ฌธ ์ค๋น๋ฅผ ๋ํ๋ด๋ orderReady์ ํ๋๋ฅผ ์ถ๊ฐํด์
- 1) ๊ฒ์ ๊ฒฐ๊ณผ์์ ์ฅ๋ฐ๊ตฌ๋๋ก ์ถ๊ฐ๋ ๊ฒฝ์ฐ์๋ orderReady๋ฅผ false๋ฅผ ์ฃผ๊ณ
- 2) ์ฅ๋ฐ๊ตฌ๋์์ <์ฃผ๋ฌธํ๊ธฐ> ๋ฅผ ํด๋ฆญํ ๊ฒฝ์ฐ orderReady ๋ฅผ true๋ก ์
๋ฐ์ดํธํ๋ค.
- ๊ทธ๋์ ๊ฒฐ์ ํ๊ธฐ ํ์ด์ง์์ cart๋ฅผ ๋ถ๋ฌ์ฌ ๋ ์ฟผ๋ฆฌ๋ฌธ์์ orderReady๊ฐ true์ธ ์ํ๋ค๋ง ๊ฐ์ ธ์จ๋ค
- 3) ๊ฒ์ ๊ฒฐ๊ณผ์์ <๊ฒฐ์ ํ๊ธฐ>๋ฅผ ํด๋ฆญํ ๊ฒฝ์ฐ์๋ orderReady๋ฅผ ๋ฐ๋ก true๋ก ์ถ๊ฐํ ๋ค ๋ฐ๋ก ๊ฒฐ์ ํ์ด์ง๋ก ์ด๋ํ๋ค.
- ๊ทธ๋ฆฌ๊ณ ๊ฒฐ์ ํ๊ธฐ๊ฐ ์๋ฃ๋๋ฉด order ํ๋์ true๋ก ์
๋ฐ์ดํธํด์ ์ฃผ๋ฌธ ๋ชฉ๋ก์์๋ ์ฟผ๋ฆฌ๋ฌธ์ผ๋ก order true๋ก ๋ณ๊ฒฝํ์ฌ ํด๋น ๋ชฉ๋ก๋ง ๊ฐ์ ธ์ค๊ฒ ํจ
1. ๊ฒ์ ๊ฒฐ๊ณผ์์ ๊ฒฐ์ ํ๊ธฐ ํด๋ฆญํ ๊ฒฝ์ฐ
const AddPayment = async () => {
if (confirm("ํด๋น ๋์๋ฅผ ๋ฐ๋ก ๊ตฌ๋งคํ์๊ฒ ์ต๋๊น?")) {
if (!user) {
//์ ์ ๊ฐ ์์ผ๋ฉด(๋ก๊ทธ์ธ ๋์ด์์ง ์์ ๊ฒฝ์ฐ)
alert("๋ก๊ทธ์ธ์ด ํ์ํ ์๋น์ค์
๋๋ค.");
navigate("/user/login"); //๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋
} else {
//DB์ ์ ์ฅํ๋ค.
try {
await addDoc(collection(db, "cart"), {
//์ปฌ๋ ์
๋ช
-interestBooks
interestBook: book.isbn, //book id
bookTitle: book.title, //book title
bookCover: book.cover, //book cover
bookLink: book.link, //book link
bookAuthor: book.author, //book author
bookPublisher: book.publisher, //book publisher
salesPrice: book.priceSales, // book sales Price
amount: 1,
priceStandard: book.priceStandard,
order: false, //์ฃผ๋ฌธ ์๋ฃ ์ฌ๋ถ
orderReady: true, // ์ฃผ๋ฌธ ์ค๋น (๊ฒฐ์ ์ค๋น) ์๋ฃ ์ฌ๋ถ
createdAt: Date.now(), // ์์ฑ์ผ์ ์ค๋
username: user.displayName, // ์ ์ ์ด๋ฆ
userId: user.uid, // ์ ์ ์์ด๋
});
} catch (error) {
console.log(error); //์๋ฌ๋ ์ฝ์์ ์ถ๋ ฅ
}
}
navigate("/user/payment"); //๊ฒฐ์ ํ์ด์ง๋ก ์ด๋
} else {
alert("์ทจ์");
return;
}
};
2. ์ฅ๋ฐ๊ตฌ๋์์ ์ฃผ๋ฌธํ๊ธฐ ํด๋ฆญํ ๊ฒฝ์ฐ orderReady ์
๋ฐ์ดํธ
//์ฃผ๋ฌธํ๊ธฐ ํด๋ฆญ ํ ๊ฒฝ์ฐ ๋ฌธ์์ orderReady์ ์
๋ฐ์ดํธํ๋ค.
const handleOrderReady = async (bookIds) => {
// ๊ฐ๊ฐ์ ์ฑ
(book) ID์ ๋ํด ์ฃผ๋ฌธ์ ์๋ฃํฉ๋๋ค.
bookIds.forEach(async (bookId) => {
const q = query(
collection(db, "cart"),
where("userId", "==", user.uid),
where("interestBook", "==", bookId),
where("order", "==", false), //์ฃผ๋ฌธ ํ๊ธฐ ์ ์ํ
where("orderReady", "==", false)
);
const querySnapshot = await getDocs(q);
querySnapshot.forEach(async (doc) => {
try {
const docRef = doc.ref;
await updateDoc(docRef, {
orderReady: true, //์ฃผ๋ฌธ ์ค๋น ์๋ฃ
});
} catch (error) {
console.error(error);
}
});
});
};
//์ฃผ๋ฌธํ๊ธฐ ํด๋ฆญ ์
const handleClickPayment = () => {
if (userCart.length === 0) {
alert("์ฅ๋ฐ๊ตฌ๋์ ์ํ์ด ์์ต๋๋ค!");
return;
} else if (userCart.length >= 1) {
if (confirm("์ฃผ๋ฌธํ์๊ฒ ์ต๋๊น?")) {
const bookIds = userCart.map((cart) => cart.interestBook);
handleOrderReady(bookIds);
navigate("/user/payment");
}
return;
}
};
3. ๊ฒฐ์ ํ๊ธฐ ํ๋ฉด
//์ฅ๋ฐ๊ตฌ๋ ๊ฐ์ ธ์ค๋ ํจ์
const fetchUserCart = async () => {
if (user) {
//์ ์ ๊ฐ ์์ ๊ฒฝ์ฐ
const q = query(
collection(db, "cart"),
where("userId", "==", user.uid), //๋ก๊ทธ์ธ ํ ์ ์ ์ ๋์ผํ ๋ฐ์ดํฐ๋ง
where("order", "==", false), //์ฃผ๋ฌธ ํ๊ธฐ ์ ์ํ
where("orderReady", "==", true)
);
//์ค์๊ฐ ๊ฐ์ ธ์ค๊ธฐ
onSnapshot(q, (snapshot) => {
const userCart = snapshot.docs.map((doc) => doc.data());
const amountResult = snapshot.docs.map((doc) => doc.data().amount);
setUserCart(userCart);
setAmount(amountResult);
//console.log(totalPrice);
});
}
};
๋ค์ ์ฐํธ๋ฒํธ ์ฐพ๊ธฐ api ์ฌ์ฉํด์
์ฐํธ ๋ฒํธ ์ฐพ์ ์ ์๊ณ , ์ด ๊ฐ๋ค์ state๋ก ๊ด๋ฆฌํด์ ์๋์ผ๋ก input์ ๊ฐ์ ธ์ค๊ฒ ๋ง๋ฌ
const [userFullAddress, setFullAddress] = useState(""); //์ ์ ์ฃผ์
const [userZoneCode, setUserZoneCode] = useState(""); //์ ์ ์ฐํธ๋ฒํธ
//๋ค์ ์ฐํธ๋ฒํธ ์ฐพ๊ธฐ API์ฌ์ฉ
const open = useDaumPostcodePopup(postcodeScriptUrl);
const handleComplete = (data) => {
let fullAddress = data.address;
let extraAddress = "";
let zonecode = data.zonecode;
if (data.addressType === "R") {
if (data.bname !== "") {
extraAddress += data.bname;
}
if (data.buildingName !== "") {
extraAddress +=
extraAddress !== "" ? `, ${data.buildingName}` : data.buildingName;
}
fullAddress += extraAddress !== "" ? ` (${extraAddress})` : "";
}
setFullAddress(fullAddress); // e.g. '์์ธ ์ฑ๋๊ตฌ ์์ญ๋ฆฌ๋ก2๊ธธ 20 (์ฑ์๋1๊ฐ)'
setUserZoneCode(zonecode);
};
const handleClick = () => {
open({ onComplete: handleComplete });
};
<input type="text" defaultValue={userZoneCode} required />
<input
className="infoInput"
type="text"
defaultValue={userFullAddress}
required
/>
4.๊ฒฐ์ ์๋ฃ ํ๋ฉด
order -> true๋ก ์
๋ฐ์ดํธ
์ฃผ๋ฌธ ์์ธ ํ์ธ์ผ๋ก ๋ง์ดํ์ด์ง์ ์๋ ์ฃผ๋ฌธ/๊ฒฐ์ ๋ชฉ๋ก์ผ๋ก ์ด๋ํ๋ค.
onClick={() => navigate("/user/mypage?order=true")}
๋ง์ดํ์ด์ง๋ ๋ฉ๋ด๋ฅผ ์ ํํด์ state์ ๊ฐ์ ์
๋ฐ์ดํธํ๊ณ ๊ทธ ๊ฐ์ ๋ง๊ฒ ํ์ด์ง๊ฐ ์ถ๋ ฅ๋๊ฒ ๊ตฌ์ฑํด๋์
๋ํดํธ ๊ฐ์ ๊ด์ฌ ๋์ ๋ฉ๋ด์ด๋ค.
<div className="userpageContainer">
<div className="aside">
<h3>๋ง์ดํ์ด์ง</h3>
<br />
<ul>
<li onClick={() => handleChange("๊ด์ฌ ๋์")}>๊ด์ฌ ๋์</li>
<li onClick={() => handleChange("์ฃผ๋ฌธ ๋ชฉ๋ก")}>์ฃผ๋ฌธ/๊ฒฐ์ ๋ชฉ๋ก</li>
</ul>
</div>
<div className="mypage">
<h2>{selectedMenu}</h2>
<div className="mypageContent">
{/* ๊ด์ฌ ๋์ ์ปดํฌ๋ํธ */}
{selectedMenu === "๊ด์ฌ ๋์" ? <InterestedBook /> : ""}
{selectedMenu === "์ฃผ๋ฌธ ๋ชฉ๋ก" ? <OrderPage /> : ""}
</div>
</div>
</div>
๊ทธ๋์
์ฃผ๋ฌธ ์ฑ๊ณตํ์ด์ง์์ ๋์ด์จ ํ๋ผ๋ฏธํฐ๊ฐ์ ๋ฐ์์ state์ ์ ์ผ ์ฒ์ ์ธํ
ํด์ฃผ๋ฉด
const queryString = useLocation().search;
const queryParams = new URLSearchParams(queryString);
const query = queryParams.get("order"); // q์ ํด๋นํ๋ ๊ฐ์ ์ฟผ๋ฆฌ์คํธ๋ง์์ ๊ฐ์ ธ์ด
const [selectedMenu, setSelectedMenu] = useState("๊ด์ฌ ๋์");
//์ฃผ๋ฌธ ์๋ฃ์์ ๋์ด์ฌ ๋
useEffect(() => {
if (query === "true") {
setSelectedMenu("์ฃผ๋ฌธ ๋ชฉ๋ก");
}
}, [query]);
์ฃผ๋ฌธ ์ฑ๊ณต ํ์ด์ง์์ ๋์ด์ค๋ฉด ๋ฐ๋ก ์ฃผ๋ฌธ ๋ชฉ๋ก ํ์ด์ง๋ก ๋์ด๊ฐ๋ค
ํ์ฌ๋ก์จ ํ๊ฐ์ง ์์ ํด์ผํ ๊ฒ
๊ฒฐ์ ํ๊ธฐ ํ์ด์ง๊น์ง ๋์ด๊ฐ๋๋ฐ ํ์ด์ง๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ์๋ orderReady๊ฐ true๋ก ๋ณ๊ฒฝ๋์ด ์๋ ์ํ์์ ๋ฒ์ด๋๋ค๋ณด๋
์ฅ๋ฐ๊ตฌ๋์์ ๋ณด์ด์ง ์๋ ํ์์ด ์์ ใ
๊ทธ๋์ ์ฐพ์๋ณด๋๊น
๋ฆฌ์กํธ ๋ผ์ฐํฐ์์ ๊ธฐ๋ฅ ์ค ํ๋์ธ Prompt๋ฅผ ์ฌ์ฉํด๋ณผ๋ ค๊ณ ํจ
https://minjung-jeon.github.io/React-Prompt/
[React] react-router Prompt ์ปค์คํฐ๋ง์ด์ง, ํ์ด์ง ์ด๋ ์ ์ด | MINJUNG
Prompt ์ปค์คํฐ๋ง์ด์ง, ํ์ด์ง ์ด๋ ์ ์ด
minjung-jeon.github.io