-
Notifications
You must be signed in to change notification settings - Fork 26
React 박신천 sprint5 #119
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
React 박신천 sprint5 #119
The head ref may contain hidden characters: "React-\uBC15\uC2E0\uCC9C-sprint5"
Conversation
|
스프리트 미션 하시느라 수고 많으셨어요. |
commit 단위를 더욱 자주, 작게 해보시는건 어떠실까요?git을 다룰 때 commit은 "언제 해야 하는가"를 생각해보신 적 있으신가요?
그럼 커밋을 언제 해야 할까요?저는 다음과 같은 룰을 지키며 커밋을 하는걸 권장 드립니다:
관련하여 읽으시면 좋은 아티클을 추천드릴게요:tl;dr관련 변경 사항 커밋 자주 커밋 미완성 작업을 커밋하지 마십시오 커밋하기 전에 코드를 테스트하세요 |
커밋 타입도 한 번 고려해보세요 !tl;dr:커밋 메시지 형식 type: Subject
body
footer기본적으로 3가지 영역(제목, 본문, 꼬리말)으로 나누어졌다. 메시지 type은 아래와 같이 분류된다. 아래와 같이 소문자로 작성한다. |
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.
.gitignore를 작성해보시는게 어떨까요?
macos의 압축 과정에서 흔히 .DS_Store 파일이 들어가는 경우가 있습니다.
해당 파일은 프로젝트와 무관하므로 .gitignore에 다음과 같이 작성하시면 git의 추적을 무시할 수 있습니다.
.DS_Store
| }) { | ||
| const query = `page=${page}&pageSize=${pageSize}&orderBy=${orderBy}&keyword=${keyword}`; | ||
| const res = await fetch( | ||
| `https://panda-market-api.vercel.app/products?${query}` |
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.
Base URL은 따로 정의해두는게 좋겠군요 !
| `https://panda-market-api.vercel.app/products?${query}` | |
| `${BASE_URL}/products?${query}` |
https://panda-market-api.vercel.app는 앞으로도 계속 사용 될 것이며, 변경될 수도 있기에 따로 정의해볼 수 있습니다 !
더 좋은 방법 ! base URL은 환경 변수에 저장하시는게 좋습니다!
환경 변수(Environment Variable):
process.env에 내장되며 앱이 실행될 때 적용할 수 있는 값입니다!
다음과 같이 적용할 수 있습니다:
// .env.development
REACT_APP_BASE_URL="http://localhost:3000"
// .env.production
REACT_APP_BASE_URL="http://myapi.com"
// 사용시
<a href={`${process.env.REACT_APP_BASE_URL}/myroute`}>URL</a>
왜 환경 변수에 저장해야 하나요?
개발(dev), 테스트(test), 실제 사용(prod) 등 다양한 환경에서 앱을 운영하게 되는 경우, 각 환경에 따라 다른 base URL을 사용해야 할 수 있습니다. 만약 코드 내에 하드코딩되어 있다면, 각 환경에 맞춰 앱을 배포할 때마다 코드를 변경해야 하며, 이는 매우 번거로운 작업이 됩니다. 하지만, 환경 변수를 .env.production, .env.development, .env.test와 같이 설정해두었다면, 코드에서는 단지 다음과 같이 적용하기만 하면 됩니다.
const apiUrl = `${process.env.REACT_APP_BASE_URL}/api`;
이러한 방식으로 환경 변수를 사용하면, 배포 환경에 따라 쉽게 URL을 변경할 수 있으며, 코드의 가독성과 유지보수성도 개선됩니다.
실제 코드 응용과 관련해서는 다음 한글 아티클을 참고해보세요! => 보러가기
| keyword = "", | ||
| }) { | ||
| const query = `page=${page}&pageSize=${pageSize}&orderBy=${orderBy}&keyword=${keyword}`; | ||
| const res = await fetch( |
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를 사용해보는건 어떨까요?
현재 fetch를 그대로 사용해도 동작은 하겠으나, 반복되는 baseURL과 fetch로 받은 response에 대한 공통적인 후처리, request 보내기 전 공통적인 처리 등 또한 고려해볼 수 있을거예요.
다음 사항들을 고려해볼 수 있어요:
- 만약
get이 아닌 메써드(post,patch,delete등)일 경우는 어떻게 처리할 수 있을까요? query와body가 필요할 때는 어떻게 처리 할 수 있을까요?- 로그인 인가를 위한 토큰을 request 전에 자동으로 삽입할 수는 없을까요? (인증/인가를 자동으로 할 수 없을까요?)
- 처음 한 번에 Base URL을 지정할 수는 없을까요?
- Base URL을 사용하다가 다른 엔드포인트에 요청해야 할 때는 어떻게 할 수 있을까요?
이 모든 요구사항들을 반영한 아키텍쳐를 구상하기는 어렵습니다. 따라서 이 모든 요구사항이 잘 만족하는 http client를 사용해보시는건 어떨까요 ?
- 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.
어떻게 세팅하면 될까? 🤔
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사용 방법 🚀
사용 방법은 정말 간단해요. 다음과 같이 사용할 수 있습니다:
instance.get(`/user/${userId}`)딱 보니. 마이그레이션도 정말 쉽게 할 수 있겠죠? 😊
| <Link to="/" className="head_logo"> | ||
| <img src={Logo} alt="판다마켓 로고" /> | ||
| </Link> |
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.
굿굿 ~ react-router-dom에서 제공하는 Link를 사용하셨군요 👍
| console.log(isTablet, "isTablet"); | ||
| const { matches: isDesktop } = window.matchMedia( | ||
| "screen and (min-width: 1024px)" | ||
| ); | ||
| console.log(isDesktop, "isDesktop"); |
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.
console.log들은 지워도 될 것 같군요 ! 😉
| console.log(isTablet, "isTablet"); | |
| const { matches: isDesktop } = window.matchMedia( | |
| "screen and (min-width: 1024px)" | |
| ); | |
| console.log(isDesktop, "isDesktop"); | |
| const { matches: isDesktop } = window.matchMedia( | |
| "screen and (min-width: 1024px)" | |
| ); |
| const getFilteredData = () => items; | ||
| const filteredItems = getFilteredData(); | ||
|
|
||
| const MAXPAGE = 5; |
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.
해당 상수도 컴포넌트 바깥으로 빼는게 좋겠어요 !
리렌더링 시 불필요한 재선언과 컴포넌트 자원을 사용하지 않는 로직을 구분할 수 있게 됩니다 😉
| const getFilteredData = () => items; | ||
| const filteredItems = getFilteredData(); |
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.
혹시 items와 filteredItems의 내용은 같은거 아닐까요?
| const getFilteredData = () => items; | |
| const filteredItems = getFilteredData(); |
items를 사용하면 될 것 같은데 getFilteredData`를 선언하고 호출하지 않으셔도 될 것으로 보여요 😉
|
|
||
| const MAXPAGE = 5; | ||
|
|
||
| const focusPage = (n) => document.getElementById(`page${n}`).focus(); |
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.
혹시 해당 로직이 왜 필요한지 알 수 있을까요 ?
| <button id="page1" onClick={() => goPage(1)}> | ||
| 1 | ||
| </button> | ||
| <button id="page2" onClick={() => goPage(2)}> | ||
| 2 | ||
| </button> | ||
| <button id="page3" onClick={() => goPage(3)}> | ||
| 3 | ||
| </button> | ||
| <button id="page4" onClick={() => goPage(4)}> | ||
| 4 | ||
| </button> | ||
| <button id="page5" onClick={() => goPage(5)}> | ||
| 5 | ||
| </button> |
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.
페이지네이션은 동적으로 바뀌어야 합니다 😉
현재 정적으로 5개까지만 보여지는데 현재 활성화 된 페이지에 맞는 페이지네이션이 필요합니다 ! (디자인 시안 참고)
|
크으... 신천님.. 정말 멋집니다. 함께 더욱 더욱 빠르게 성장해봅시다 ! 스프린트 미션 수행하시느라 정말 수고 많으셨습니다. |
요구사항
기본
배포 링크
중고마켓
중고마켓 반응형
베스트 상품
Desktop : 4개 보이기
Tablet : 2개 보이기
Mobile : 1개 보이기
전체 상품
Desktop : 12개 보이기
Tablet : 6개 보이기
Mobile : 4개 보이기
심화
주요 변경사항
등을 구현했습니다
스크린샷
멘토에게