-
Notifications
You must be signed in to change notification settings - Fork 42
[박준현] sprint5 #216
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-\uBC15\uC900\uD604-sprint5"
[박준현] sprint5 #216
Conversation
[Fix] delete merged branch github action
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.
수고하셨습니다!
첫 리액트 미션인데 조금만 다듬어보시면 많이 좋아질것같아요 :)
코멘트 남겨드린거 참고해보시고, 리팩토링해보세요!
주요 리뷰 포인트
- 불필요한 폴더(사용하지않는 폴더&파일) 제거하기
- 포맷팅
- App.jsx에서 data fetching 하지 않기
- 컴포넌트 로직 순서 유의해서 작성하기
- 재사용 가능한 로직을 커스텀 훅으로 분리하기
- 하드코딩된 값을 가능한 상수로 바꿔주기
- 컴포넌트 분리하기
vite-project/.gitignore
Outdated
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.
루트에서 또 vite-project라는 폴더를 만들어서 관리하시고계시는데, 보통은 여러 프로젝트의 종속성 공유를 위해 모노레포 세팅을 하지않는 이상 이런 세팅을 하지 않아서 불필요한 폴더를 정리해주시는게 좋을것같네요!
vite-project/css/login-signup.css
Outdated
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.
전체적으로 포맷팅이 일관적이지않아서, 규칙을 지켜서 자동으로 포맷팅하는 도구를 사용해보시면 좋을것같네요.
기본적인 linter 검사 + 포맷팅 수행을 위해 아래 아티클 참고해보시고, 자동 저장 옵션과 함께 활용해보시면 좋을것같아요!
vite-project/src/App.jsx
Outdated
<Navbar /> | ||
<Routes> | ||
<Route | ||
path="/" | ||
element={<PandaMarketPage />} // 메인 페이지 | ||
/> | ||
<Route | ||
path="/items" | ||
element={ | ||
<Products allProducts={allProducts} bestProducts={bestProducts} /> | ||
} | ||
/> | ||
<Route path="/login" element={<Login />} /> | ||
<Route path="/signup" element={<Signup />} /> | ||
<Route path="/faq" element={<Faq />} /> | ||
<Route path="/additem" element={<AddItem />} /> | ||
</Routes> |
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.
해당 컴포넌트는 이 리턴문에서 리턴되는 모든 컴포넌트를 렌더링할때 쓰입니다.
즉, 이 컴포넌트에서 data fetching을 시도하게되면 Login 페이지에서는 필요하지도 않은 자원이 요청되고, 초기 로딩이 지연되는 상황이 발생하겠죠?
따라서 해당 data fetching 로직은 필요한 컴포넌트에서만 (Products 컴포넌트에서) 직접 데이터를 가져오도록 옮기시는게 더 나은 구조를 위한 관심사 분리 원칙에서도, 성능을 위해서도 좋은 선택입니다.
state 관리 & data fetching 로직을 Products 컴포넌트에서 직접 하도록 옮겨봅시다!
vite-project/src/api/index.js
Outdated
@@ -0,0 +1,29 @@ | |||
const BASE_URL = "https://panda-market-api.vercel.app"; |
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 base url의 경우, 외부 노출에 민감한 정보여서 환경변수로 관리하는걸 추천드립니다!
* @param {object} params - 쿼리 파라미터 (기본값: 빈 객체) | ||
* @returns {Promise<array>} - API로부터 받아온 list 데이터 반환 | ||
*/ | ||
export async function fetchData(endpoint, params = {}) { |
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.
이 함수는 jsdoc도 쓰시고 재사용성을 잘 고려해서 작성하셨네요 👍 굳굳!
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.
해당 파일의 핵심 로직은 스타일링이 아니라 컴포넌트를 구성하는 로직이기때문에,
스타일드 컴포넌트보다 컴포넌트 작성 로직이 항상 순서가 먼저 올수있도록 염두에 두고 작성해봅시다!
useEffect(() => { | ||
function updateImgCount() { | ||
const width = window.innerWidth; | ||
if (width >= 1200) setImgCount(10); | ||
else if (width >= 768) setImgCount(6); | ||
else setImgCount(4); | ||
} | ||
updateImgCount(); | ||
window.addEventListener("resize", updateImgCount); | ||
return () => window.removeEventListener("resize", updateImgCount); | ||
}, []); |
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.
스크린 사이즈를 감지해 이미지 갯수를 업데이트하는 로직처럼 보이네요!
아래 예시와 같이 재사용 가능한 로직 (스크린 사이즈 감지)은 커스텀 훅으로 분리해 사용해주면 코드 중복을 줄일 수 있겠죠?
import { useEffect, useState } from "react";
export const useScreenSize = () => {
const [isDesktop, setIsDesktop] = useState(false);
const [isTablet, setIsTablet] = useState(false);
const [isMobile, setIsMobile] = useState(true);
useEffect(() => {
function updateScreenSize() {
const width = window.innerWidth;
setIsDesktop(width >= 1200);
setIsTablet(width >= 768 && width < 1200);
setIsMobile(width < 768);
}
updateScreenSize();
window.addEventListener("resize", updateScreenSize);
return () => window.removeEventListener("resize", updateScreenSize);
}, []);
return { isDesktop, isTablet, isMobile };
};
그리고, 이 커스텀 훅을 사용해 <AllProducts />
컴포넌트에서는 브레이크포인트별 이미지를 몇개씩 보여줄지만 상수로 정해주고
// 상수 정의
const IMG_COUNTS = {
desktop: 10,
tablet: 6,
mobile: 4,
};
const { isDesktop, isTablet } = useScreenSize();
// 화면 크기에 따른 상품 개수 계산
const imgCount = isDesktop
? IMG_COUNTS.desktop
: isTablet
? IMG_COUNTS.tablet
: IMG_COUNTS.mobile;
이렇게 화면 크기에 따른 이미지 개수만 계산해주면 되겠죠? :)
useEffect(() => { | ||
function updateImgCount() { | ||
const width = window.innerWidth; | ||
if (width >= 1200) setImgCount(4); |
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.
해당 컴포넌트에서도 위 코멘트 참고하셔서 리팩토링해보세요!
그리고 항상 하드코딩하는 값보다는 상수를 활용할수있도록 신경써주시면 좋습니다 :)
<div className="signup-password-box"> | ||
<h4>비밀번호</h4> | ||
<input | ||
type="password" | ||
className="signup-password-input SignupInput" | ||
required | ||
/> | ||
<h4 | ||
className="error-msg" | ||
style={{ color: "red", display: "none", fontSize: "12px" }} | ||
> | ||
비밀번호를 입력해주세요. | ||
</h4> | ||
</div> |
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.
일정한 구조로 반복되는 코드들이 보이죠~? 이런 코드들이 단위 기능을 가지고있기도 하고요 (인풋 필드).
이런 경우, 컴포넌트 분리를 해주시면 유지보수에 훨씬 좋겠죠?
요구사항
기본
베스트 상품
Desktop : 4개 보이기
Tablet : 2개 보이기
Mobile : 1개 보이기
전체 상품
Desktop : 12개 보이기
Tablet : 6개 보이기
Mobile : 4개 보이기
스크린샷
멘토에게