-
Notifications
You must be signed in to change notification settings - Fork 20
[유선향]-sprint8 #71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "React-\uC720\uC120\uD5A5-sprint8"
[유선향]-sprint8 #71
Changes from all commits
8d73d8c
409ee54
78c3078
86e69a5
930dba9
addb51f
fecbd64
f8d651c
b87b91b
46d3ce6
1cb5a08
167dcc0
212edd8
a04e631
3210bd4
9dac8e0
8f838ca
b960234
7bb8e24
3f77bf3
ef38e4e
a1639f6
3731caa
5fdcc0e
0c34f84
a8fd50d
8186da1
c5fea26
de53246
6352933
d0b343e
7e56e15
a4011fe
3ee9850
6dc1fab
b4c2a29
b562007
cd7f584
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,53 +1,11 @@ | ||
| import { Route, BrowserRouter, Routes } from "react-router-dom"; | ||
| import { createGlobalStyle } from "styled-components"; | ||
| import GlobalStyle from "./style/globalStyle.js"; | ||
| // | ||
| import LandingPage from "./pages/LandingPage/LandingPage.jsx"; | ||
| import App from "./App.js"; | ||
| import HomePage from "./pages/HomePage/HomePage.jsx"; | ||
| import AddItem from "./pages/AddItem/AddItem.jsx"; | ||
| import Product from "./pages/ProductPage/Product.jsx"; | ||
| import Test from "./components/TestPage.jsx"; | ||
| // | ||
| // | ||
| const GlobalStyle = createGlobalStyle` | ||
| * { | ||
| box-sizing: border-box; | ||
| } | ||
| body { | ||
| font-family: 'Pretendard', sans-serif; | ||
| font-display: swap; | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| html { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| a { | ||
| text-decoration: none; | ||
| color: #ffffff; | ||
| } | ||
| p{ | ||
| margin: 0px; | ||
| } | ||
| @font-face { | ||
| font-family: 'Pretendard'; | ||
| src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/[email protected]/Pretendard-Regular.woff2') format('woff2'); | ||
| src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/[email protected]/Pretendard-Regular.woff') format('woff'); | ||
| font-display: swap; | ||
| font-weight: 400; | ||
| font-style: normal; | ||
| } | ||
|
|
||
| @font-face { | ||
| font-family: "Pretendard"; | ||
| src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/[email protected]/Pretendard-Bold.woff2') format('woff2'); | ||
| src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/[email protected]/Pretendard-Bold.woff') format('woff'); | ||
| font-display: swap; | ||
| font-weight: 600; | ||
| font-style: normal; | ||
| } | ||
| `; | ||
| import ItemsPage from "./pages/ItemsPage/ItemsPage.tsx"; | ||
| import AddItem from "./pages/AddItem/AddItem.tsx"; | ||
| import Product from "./pages/ProductPage/Product.tsx"; | ||
| // | ||
| function Main() { | ||
| return ( | ||
|
|
@@ -57,8 +15,7 @@ function Main() { | |
| <Routes> | ||
| <Route path="/" element={<LandingPage />} /> | ||
| <Route element={<App />}> | ||
| <Route path="/test" element={<Test />} /> | ||
| <Route path="/items" element={<HomePage />} /> | ||
| <Route path="/items" element={<ItemsPage />} /> | ||
| <Route path="/items/:productId" element={<Product />} /> | ||
| <Route path="/additem" element={<AddItem />} /> | ||
| </Route> | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,17 +1,17 @@ | ||||||||||||||||||||||||||||||||||||||||||||
| import axios from "axios"; | ||||||||||||||||||||||||||||||||||||||||||||
| const BASE_URL = "https://panda-market-api.vercel.app"; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| export async function getProductComments(productId, limit = 3) { | ||||||||||||||||||||||||||||||||||||||||||||
| export async function getProductComments({ productId }: Params, limit = 3) { | ||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||
| const res = await axios.get( | ||||||||||||||||||||||||||||||||||||||||||||
| `${BASE_URL}/products/${productId}/comments?limit=${limit}` | ||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||
| if (!res) { | ||||||||||||||||||||||||||||||||||||||||||||
| throw new Error("리뷰 불러오기 실패"); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| return res.data; | ||||||||||||||||||||||||||||||||||||||||||||
| const data: Comment[] = res.data.list; | ||||||||||||||||||||||||||||||||||||||||||||
| return data; | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+4
to
+13
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 다음과 같이 제네릭을 통해서 타입을 정의할 수 있어요 !
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||
| console.error(error); | ||||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,60 @@ | ||||||||||||||
| import axios from "axios"; | ||||||||||||||
| const BASE_URL = "https://panda-market-api.vercel.app"; | ||||||||||||||
| // | ||||||||||||||
|
|
||||||||||||||
| export interface ResponseData extends Product { | ||||||||||||||
| createdAt: string; | ||||||||||||||
| favoriteCount: number; | ||||||||||||||
| ownerNickname: string; | ||||||||||||||
| ownerId: number; | ||||||||||||||
| id: number; | ||||||||||||||
| isFavorite: boolean; | ||||||||||||||
| } | ||||||||||||||
| export type Item = Omit<ResponseData, "ownernickname" | "isFavorite">; | ||||||||||||||
|
|
||||||||||||||
| export async function getProducts({ | ||||||||||||||
| device = "desktop", | ||||||||||||||
| page = 1, | ||||||||||||||
| selectedOrder = "최신순", | ||||||||||||||
| }) { | ||||||||||||||
| const order = selectedOrder === "최신순" ? "recent" : "favorite"; | ||||||||||||||
| const pageSize = device === "mobile" ? 4 : device === "tablet" ? 6 : 10; | ||||||||||||||
| const query = `?orderBy=${order}&page=${page}&pageSize=${pageSize}`; | ||||||||||||||
|
Comment on lines
+20
to
+22
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 쿼리는
|
||||||||||||||
| const order = selectedOrder === "최신순" ? "recent" : "favorite"; | |
| const pageSize = device === "mobile" ? 4 : device === "tablet" ? 6 : 10; | |
| const query = `?orderBy=${order}&page=${page}&pageSize=${pageSize}`; | |
| const order = selectedOrder === "최신순" ? "recent" : "favorite"; | |
| const pageSize = device === "mobile" ? 4 : device === "tablet" ? 6 : 10; | |
| const query = new URLSearchParams({order, page, pageSize}).toString(); |
URLSearchParams와 함께 객체로 손쉽게 핸들링할 수 있습니다 !
객체로 구성할 수 있어 가독성이 좋고, URL 인코딩을 자동으로 처리하여 특수 문자나 공백이 포함된 값에서도 안전하게 동작합니다 !
URLSearchParams:
URLSearchParams인터페이스는 URL의 쿼리 문자열을 대상으로 작업할 수 있는 유틸리티 메서드를 정의합니다.
쿼리를 생성하실 때에 참고해서 사용해보세요 😊
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
또한
axios를 사용중이시라면instnace를 생성하셔서 사용해보실 것을 권장드립니다 !BASE_URL을 매번 입력하셔야 하며, 각기 다른 엔드포인트와 그에 따른 설정이 필요할 때에 유지보수가 어려울 수 있어요:어떻게 세팅하면 될까? 🤔
instance를 만들어서export를 하고 사용해보는 것 정도로 시도해보면 좋을 것 같아요.axios-instance파일을 만들어서instance를 생성하고export한 후 사용해보는건 어떨까요?다음과 같이 만들어볼 수 있어요:
인가에 필요한
accessToken을localStorage가 있다면 axios의 인터셉터를 활용할 수 있습니다 !사용 방법 🚀
사용 방법은 정말 간단해요. 다음과 같이 사용할 수 있습니다:
딱 보니. 마이그레이션도 정말 쉽게 할 수 있겠죠? 😊