-
Notifications
You must be signed in to change notification settings - Fork 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
[채종민] sprint10 #626
The head ref may contain hidden characters: "Next.js-\uCC44\uC885\uBBFC-sprint10"
[채종민] sprint10 #626
Conversation
수고 하셨습니다 ! 스프리트 미션 하시느라 정말 수고 많으셨어요. 1. 코드 관련
2. post 요청 response는 받아서 확인하나요? 아니면 그냥 버리나요?
3. post로 데이터 수정한 다음에 get api 함수로 화면 업데이트를 하나요(예를 들면 새로고침...)
낙관적 업데이트란?낙관적 업데이트(Optimistic Updates)는 웹 애플리케이션에서 사용자 경험을 개선하기 위해 사용되는 기술입니다. 이 기술은 사용자 인터페이스(UI)가 서버로부터 응답을 받기 전에 미리 업데이트되도록 합니다. 이를 통해 사용자는 즉각적인 피드백을 받고, 애플리케이션이 더 빠르고 반응성 있게 느껴집니다. 낙관적 업데이트는 특히 데이터 변경이 자주 발생하는 애플리케이션에서 유용합니다. 작동 원리 1. 로컬 상태 업데이트: 2. 서버 요청: 3. 서버 응답: 4. 상태 동기화: 장점 단점 |
수고 정말 많으셨어요. 리뷰 중 궁금하신거 있으시면 사전 질의를 통해서 남겨주시거나 멘토링 미팅 때 질문주세요 ㅎㅎㅎ |
REACT_APP_API_URL = https://panda-market-api.vercel.app/ | ||
|
||
NEXT_PUBLIC_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.
.gitignore
에 env파일을 추가해 주셨군요!
하지만 아직 github에서 확인되는 걸 보니 캐시를 지워줘야 할 것으로 보입니다 :)
git rm .env --chached
gitignore에 .env 파일을 추가해도 commit history에 env파일이 남아있게 됩니다!
git에 env파일을 완전히 지우려면 추가 작업이 필요해요 😂
아래 블로그를 참고해 보시면 좋을 것 같아요!
interface Response { | ||
createdAt: string; | ||
updatedAt: string; | ||
likeCount: number; | ||
writer: { | ||
id: number; | ||
nickname: string; | ||
}; | ||
image: string | null; | ||
content: string; | ||
title: string; | ||
id: number; | ||
} |
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.
중복되는 코드(타입)를 하나의 파일에서 관리해 보면 어떨까요?!
Response
는 getArticle.ts
에서 사용한 타입과 중복되는 내용으로 보여요.😂
interface ArticleType {
updatedAt: string;
createdAt: string;
likeCount: number;
writer: {
id: number;
nickname: string;
};
image: string | null;
content: string;
title: string;
id: number;
}
공통적으로 사용되는 타입은type.ts
파일을 만들고 관리하면 좋을 것 같아요!
타입이 여러 곳에 중복되어 정의되어 있으면, 변경이 필요할 때마다 모든 정의를 일일이 수정해야 합니다. 타입을 하나의 코드로 관리하면 한 곳에서 수정하면 되므로 유지보수가 훨씬 용이합니다. 😊
const accessToken = localStorage.getItem("accessToken"); | ||
if (image) { | ||
const imageUrl = await postImage({ image }); | ||
console.log(imageUrl); |
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는 pull request 전에 제거해 주시는 게 좋아요!
작업한 내용을 commit 하기 전에 불필요한 로깅은 지워주면 좋아요! 로그가 남으면 남을 수록 추 후 디버깅이 어려워집니다.. 하핳ㅎ
개인적인 팁 !
저는 다음과 같이 저만의 식별 $$
과 같은 값을 앞에 두는 버릇이 있는데 크롬/VSCode에서 콘솔 검색할 때 편하더라구염
console.log(imageUrl); | |
console.log('$$ imageUrl: ', imageUrl); |
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.
그리고 add
할 때 -p
옵션을 줘보세요 !
git add . -p
를 사용하게 되면 변경사항을 스테이징에 올릴 때 파일 내 코드 단위로 잘라서 올릴 수 있습니다 ! 상당히 유용하므로 히스토리를 신경쓰신다면 꼭 사용해보세요 😊
어떻게 사용하지?
git add . -p
try { | ||
const accessToken = localStorage.getItem("accessToken"); | ||
const { data } = await axiosInstance.post<Response>( | ||
`articles/${articleId}/comments`, | ||
{ content }, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${accessToken}`, | ||
}, | ||
} | ||
); | ||
return data; |
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
의 메써드인 interceptors
를 통하여 미들웨어로 인가를 처리하는 예제예요 ! 한 번 확인해보시고 적용하시는 것도 고려해보세요 😊😊😊
instance.interceptors.request.use(
(config) => {
const accessToken = localStorage.getItem('accessToken')?.replace(/"/gi, '');
if (!accessToken) return config;
config.headers.Authorization = accessToken;
return config;
},
(error) => {
return Promise.reject(error);
}
);
instance.interceptors.response.use(
(response) => {
return response;
},
(error) => {
alert(`ERROR: ${error.response.data.message} `);
return Promise.reject(error);
}
);
return ( | ||
<Image | ||
src={ic_heart} | ||
alt="하트 버튼" | ||
width={width} | ||
height={height} | ||
className="cursor-pointer" | ||
onClick={onClick} | ||
/> | ||
); |
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.
Image 태그의 onClick
- nextjs의 Image는 onClick을 지원하지 않아요! 참고자료
- 만약 작동하지 않는 다면 아래와 같이 상위 요소로 감싸서 이용하실 수 있습니다 😊
return ( | |
<Image | |
src={ic_heart} | |
alt="하트 버튼" | |
width={width} | |
height={height} | |
className="cursor-pointer" | |
onClick={onClick} | |
/> | |
); | |
return ( | |
<button type="button" onClick={onClick}> | |
<Image | |
src={ic_heart} | |
alt="하트 버튼" | |
width={width} | |
height={height} | |
className="cursor-pointer" | |
/> | |
</button> | |
); |
desktop: number; | ||
tablet: number; | ||
mobile: number; | ||
} | ||
type useSetNumOfItemsToShowType = (prop: propType) => number; | ||
type useSetNumOfItemsToShowType = (prop: PropType) => number; |
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.
type은 파스칼 케이스 사용!
깜박 하신 것 같아요. 수정해 주시면 좋을 것 같습니다 =)
width: number; | ||
height: number; | ||
disabled: boolean; | ||
children: string; |
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.
children
네이밍 개선!
- 이 부분도 목적에 맞는 네이밍을 사용하면 좋을 것 같아요!
children: string; | |
buttonLabel: string; |
.fileInput { | ||
display: none; | ||
} | ||
|
||
.btn_upload { | ||
width: 28.2rem; | ||
height: 100%; | ||
background-color: var(--coolGray100); | ||
border: none; | ||
border-radius: 1.2rem; | ||
cursor: pointer; | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: center; | ||
gap: 1.2rem; | ||
} |
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.
styles을 잘 분리해 주셨어요! 굿 👍
- 다만 표기법이 혼용된 부분은 일관되게 수정하시면 더욱 좋을 것 같습니다!
.fileInput { | |
display: none; | |
} | |
.btn_upload { | |
width: 28.2rem; | |
height: 100%; | |
background-color: var(--coolGray100); | |
border: none; | |
border-radius: 1.2rem; | |
cursor: pointer; | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
gap: 1.2rem; | |
} | |
.file_input { | |
display: none; | |
} | |
.btn_upload { | |
width: 28.2rem; | |
height: 100%; | |
background-color: var(--coolGray100); | |
border: none; | |
border-radius: 1.2rem; | |
cursor: pointer; | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
gap: 1.2rem; | |
} |
- 개인적인 생각으론 다음에는 클래스 표기를 Kebab Case로 하시는 것도 좋을 것 같아요 =)
font-size: 1.8rem; | ||
font-weight: 700; | ||
line-height: 2.1rem; | ||
color: var(--coolGray800); |
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.
컬러를 팔레트를 잘 사용해 주셨네요! 굿!
- 별도로 팔레트를 선언하고 사용해 작성해 주신 부분 너무 좋아요 👍
|
||
interface NoContentSignProp { | ||
image: StaticImageData; | ||
children: string; |
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.
children네이밍 개선!
- 일반적으로 React.ReactNode로 사용되는 경우가 많아요!
- 목적에 맞는 보다 직관적인 이름을 사용하면 혹을 것 같아요 =)
children: string; | |
label: string; |
배포: https://6-sprint-mission-git-nextjs-sprint10-jaychaes-projects.vercel.app/?_vercel_share=FTXpQDu9iYCdhDZsaIXki8XUZrqUvIzj
요구사항
기본
상품 등록 페이지 주소는 “/addboard” 입니다.
게시판 이미지는 최대 한개 업로드가 가능합니다.
각 input의 placeholder 값을 정확히 입력해주세요.
이미지를 제외하고 input 에 모든 값을 입력하면 ‘등록' 버튼이 활성화 됩니다.
회원가입, 로그인 api를 사용하여 받은accessToken을 사용하여 게시물 등록을 합니다.
‘등록’ 버튼을 누르면 게시물 상세 페이지로 이동합니다.
상품 상세 페이지 주소는 “/addboard/{id}” 입니다.
댓글 input 값을 입력하면 ‘등록' 버튼이 활성화 됩니다.
활성화된 ‘등록' 버튼을 누르면 댓글이 등록됩니다
심화
주요 변경사항
스크린샷
멘토에게
post 요청 response는 받아서 확인하나요? 아니면 그냥 버리나요?
post로 데이터 수정한 다음에 get api 함수로 화면 업데이트를 하나요(예를 들면 새로고침...)
아니면 그냥 state만 살짝 바꿔주나요? -> 이 경우면 제가 작성한 글은 실시간 적용이 되는데
다른 분들이 작성한 글은 실시간 적용이 안 되는 단점이 있는 것 같아요.