-
Notifications
You must be signed in to change notification settings - Fork 20
[황혜진] sprint7 #79
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
[황혜진] sprint7 #79
The head ref may contain hidden characters: "React-\uD669\uD61C\uC9C4-sprint7"
Conversation
|
스프리트 미션 하시느라 수고 많으셨어요. |
| <Header /> | ||
|
|
||
| <div className="withHeader"> | ||
| <Routes> | ||
| {/* React Router v6부터는 path="/" 대신 간단하게 `index`라고 표기하면 돼요 */} | ||
| <Route index element={<HomePage />} /> | ||
| <Route path="login" element={<LoginPage />} /> | ||
| <Route path="items" element={<MarketPage />} /> | ||
| <Route path="additem" element={<AddItemPage />} /> | ||
| <Route path="community" element={<CommunityFeedPage />} /> | ||
| </Routes> | ||
| </div> | ||
| </BrowserRouter> | ||
| <div className="withHeader"> | ||
| <Routes> | ||
| {/* React Router v6부터는 path="/" 대신 간단하게 `index`라고 표기하면 돼요 */} | ||
| <Route index element={<HomePage />} /> | ||
| <Route path="login" element={<LoginPage />} /> |
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.
오잉 ? 혹시 로그인 페이지에서는 Global Navigation Bar가 없지 않나요?
만약 그렇다면 react-router-dom에서 outlet을 활용해볼 수 있습니다 !
Routes에서 element를 지정하여 중첩 레이아웃을 사용할 수 있으니 참고해서 설계해보세요 😊
tl;dr
// App.tsx
<Routes>
<Route path="/" element={<Main />}> // 중첩 라우팅
<Route path="user-management" element={<UserManagement />} />
<Route path="child-management" element={<ChildManagement />} />
</Route>
<Route path="/login" element={<Login />} />
</Routes>
// Main.tsx
<MainWrapper>
<MainMenu />
<Outlet /> // children과 같은 효과 ! ✨
</MainWrapper>| const BASE_URL = process.env.REACT_APP_BASE_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.
크으 ~ 환경 변수를 잘 활용하셨네요 👍👍
| export async function getComments(productId) { | ||
| const response = await axios.get( | ||
| `${BASE_URL}/products/${productId}/comments?limit=3` | ||
| ); | ||
|
|
||
| return response.data.list || []; | ||
| } |
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.
limit을 고정하지 않고 기본값으로 넣는게 더 유연한 API 함수가 될 것 같아요 😊
| export async function getComments(productId) { | |
| const response = await axios.get( | |
| `${BASE_URL}/products/${productId}/comments?limit=3` | |
| ); | |
| return response.data.list || []; | |
| } | |
| export async function getComments(productId, limit = 3) { | |
| const response = await axios.get( | |
| `${BASE_URL}/products/${productId}/comments?limit=${limit}` | |
| ); | |
| return response.data.list || []; | |
| } |
| const response = await axios.get( | ||
| `${BASE_URL}/products/${productId}/comments?limit=3` | ||
| ); |
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.
쿼리는 URLSearchParams로 손쉽게 사용할 수 있어요 !
| const response = await axios.get( | |
| `${BASE_URL}/products/${productId}/comments?limit=3` | |
| ); | |
| const params = new URLSearchParams({ limit: '100' }); | |
| const { data } = await axios.get(`${BASE_URL}/products/${productId}/comments`, { params }); |
axios를 사용하실 경우 URLSearchParams와 함께 객체로 손쉽게 핸들링할 수 있습니다 !
객체로 구성할 수 있어 가독성이 좋고, URL 인코딩을 자동으로 처리하여 특수 문자나 공백이 포함된 값에서도 안전하게 동작합니다 !
URLSearchParams:
URLSearchParams인터페이스는 URL의 쿼리 문자열을 대상으로 작업할 수 있는 유틸리티 메서드를 정의합니다.
쿼리를 생성하실 때에 참고해서 사용해보세요 😊
| @@ -0,0 +1,12 @@ | |||
| //commentApi.js | |||
| import axios from "axios"; | |||
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.
instance를 만들어서 export를 하고 사용해볼 수 있습니다 !
axios-instance과 같은 파일을 만들어서 instance를 생성하고 export한 후 사용해보는건 어떨까요?
다음과 같이 만들어볼 수 있어요:
const baseURL = process.env.NEXT_PUBLIC_LINKBRARY_BaseURL;
const instance = axios.create({
baseURL: baseURL,
headers: {
'Content-Type': 'application/json',
},
});
export default instance인가에 필요한 accessToken을 localStorage가 있다면 axios의 인터셉터를 활용할 수 있습니다 !
인터셉터는 혼자 해결해보시는 것을 권장드립니다. 혹시 모르시겠으면 다음 위클리 미션에 질문해주세요. 😊
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.
해당 버튼은 html과 css로 만드는게 어떨까요 ?!
| fetch( | ||
| `https://panda-market-api.vercel.app/products/${productId}/comments?limit=10` | ||
| ) | ||
| .then((res) => res.json()) | ||
| .then((data) => { | ||
| setComments(data.list || []); | ||
| }) | ||
| .catch(console.error); |
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.
api 함수를 이미 만드셨으므로 해당 컴포넌트에서 fetch를 할 필요가 없어보입니다 !
다음과 같이 작성해볼 수 있겠네요 !
| fetch( | |
| `https://panda-market-api.vercel.app/products/${productId}/comments?limit=10` | |
| ) | |
| .then((res) => res.json()) | |
| .then((data) => { | |
| setComments(data.list || []); | |
| }) | |
| .catch(console.error); | |
| getComments(productId, 10) // 만약 상기 getComments limit에 대한 피드백을 수용했을 경우 두번째 파라메터가 붙습니다 ! |
|
수고하셨습니다 혜진님 !! 과제 수행하시느라 정말 수고 많으셨습니다 혜진님 ! |
요구사항
기본
[] 상품 상세 페이지 주소는 "/items/{productId}" 입니다.
response로 받은 아래의 데이터로 화면을 구현합니다
[x]favoriteCount : 하트 개수
[x]images : 상품 이미지
tags : 상품 태그
name : 상품 이름
description : 상품 설명
목록으로 돌아가기 버튼을 클릭하면 중고마켓 페이지인 주소 "/items"으로 이동 합니다
문의하기에 내용을 입력하면 등록 버튼의 색상은 "3692FF"로 변합니다.
response로 받은 아래의 데이터로 화면을 구협합니다
image : 작성자 이미지
nickname : 작성자 닉네임
content : 작성자가 남긴 문구
description : 상품 설명
updatedAt : 문의글 마지막 업데이트 시간
심화
멘토에게