-
Notifications
You must be signed in to change notification settings - Fork 35
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 #306
The head ref may contain hidden characters: "Next-\uAE40\uC815\uD604-sprint10"
[김정현] Sprint10 #306
Conversation
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 커스텀훅 분리는 처음부터 전체적으로 묶을 생각보다는 api 하나씩 커스텀 훅으로 분리해보는 걸 추천드리고, 그 뒤에 커스텀훅들 사이에서 공통적인 로직이 눈에 보인다면 그걸 또 하나의 커스텀훅으로 분리해서 리팩토링 하는 과정으로 가시는 것이 불필요한 확장성도 방지할 수 있고, 코드 구현 자체가 훨씬 쉬워질 거에요!
enum관련된 아티클 하나 첨부해드릴게요! 사용이 나쁘다는 것은 아닙니다만 이런 의견도 있다 정도만 알아두시면 좋을 것 같아요!
https://velog.io/@hhhminme/%EB%84%A4-Enum-%EB%88%84%EA%B0%80-Typescript%EC%97%90%EC%84%9C-Enum%EC%9D%84-%EC%93%B0%EB%83%90
이번 한 주도 화이팅이에요!
<form onSubmit={handleSubmitPost} className={styles.formContainer}> | ||
<div className={styles.titleContainer}> | ||
<h2>게시글 쓰기</h2> | ||
<LinkButton type="submit" isActive={!isActive} btnName="등록" /> |
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.
isActive={!isActive} 컴포넌트에 isActive를 반전시켜서 값을 넘겨주는 것 같아서 isActive라는 이름 대신 다른 이름으로 prop를 넘겨주는 것은 어떨까요?!
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.
아니면 isActive 조건을 바꿔보겠습니다!
const token = localStorage.getItem('token'); | ||
|
||
const fetchNewPostData = async () => { | ||
try { |
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.
이 부분에서 /images/upload 부분 함수를 따로 분리해주는 것이 좋겠네요!
예를 들면 이런식으로 파일을 분리할 수 있겠네요!
// axiosInstance.ts
import axios from 'axios';
const axiosInstance = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL, // 환경 변수로 설정된 API 기본 URL
timeout: 10000, // 10초 타임아웃
headers: {
'Content-Type': 'application/json',
},
});
export default axiosInstance;
// api.ts
import axiosInstance from './axiosInstance';
export const uploadImage = async (image: File, token: string) => {
const formData = new FormData();
formData.append('image', image);
const response = await axiosInstance.post('/images/upload', formData, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return response.data.url;
};
export const createArticle = async (title: string, content: string, imageUrl: string, token: string) => {
const response = await axiosInstance.post('/articles', {
title,
content,
image: imageUrl,
}, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return response.data.id;
};
|
||
interface SortOptionProps { | ||
isOpen: boolean; | ||
sortText: "recent" | "like"; |
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 enum SortOptionType {
Recent = "recent",
Like = "like",
}
sortText: SortOptionType; // 이렇게 정의해주려고 하셨던 용도가 아니였을까요!?
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 SortOptionLabels = {
[SortOptionType.Recent]: "최신순",
[SortOptionType.Like]: "좋아요순",
};
이렇게 하면 sortText의 타입을 명확하게 정의할 수 있을 뿐 아니라, SortOptionLabels를 통해서 쉽게 관리도 할 수 있을 거 같아요!
@@ -64,7 +58,7 @@ export default function Post({ initialPosts }: AllPropsListProps) { | |||
})); | |||
}; | |||
|
|||
const sortText = options.orderBy === 'recent' ? '최신순' : '좋아요순'; | |||
const sortText = options.orderBy === 'recent' ? 'recent' : 'like'; |
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.
우리 위에서 SortOptionType으로 옵션 정해준 거 불러오게 되면 오타날 일도 없고 코드 일관성도 생길 거 같지 않나요!?
const sortText = options.orderBy === SortOptionType.Recent ? SortOptionTypeLabel.Recent : SortOptionTypeLabel.Like;
|
||
function getBestPostSize() { | ||
if (typeof window === 'undefined') return 3; | ||
if (window.innerWidth <= DEVICE_SIZE.mobile) { |
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.
나중에 if-else문이 길어진다면 switch문으로 변경하는 것이 대안이 될 수 있다는 점!
page?: number; | ||
} | ||
|
||
interface IPostList { |
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.
요기서만 IPostList로 I가 붙었네용 ㅎㅎ 네이밍도 일관성있게 PostListWrapper와 같은 이름을 사용하시면 좋을 것 같아요!
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.
이름 정하는게 너무 어렵네용.. ㅠㅠ
postList: PostListProps;
로 정의만 다시 해준거라서 더 이름짓기가 어려운것 같아요
export default function CommnetForm() { | ||
const [commentValue, setCommentValue] = useState(''); | ||
const router = useRouter(); | ||
const token = localStorage.getItem('token'); |
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.
SSR환경에서 서버 사이드에서는 localStorage를 읽을 수 없기 때문에 나중에 안전성을 생각해서
useEffect(() => {
const storedToken = localStorage.getItem('token');
setToken(storedToken);
}, []);
처럼 useEffect안에서 접근하는 것이 안전할 것 같네요!
id: string | string[] | undefined | ||
) => Promise<any>; | ||
|
||
type GetFn<T> = GetPostFn | GetPostListFn | GetPostCommentFn; |
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.
GetFn가 여러 함수 타입을 포함하고 있어서 타입이 명확하지 않게 되고, 이는 어디선가 에러를 발생시킬 수 있어요!
그래서 이럴 때 사용하는게 제네릭 타입입니다 ㅎㅎ
type GetFn<T> = (params: any, id?: string | string[] | undefined) => Promise<T>;
요론식으로 제네릭 함수로 만들어주면 좋을 것 같아요 👍
const [loading, setLoading] = useState<Boolean>(false); | ||
const [error, setError] = useState<string | null>(null); | ||
const [dataList, setDataList] = useState<T[] | T | null>(initialList); | ||
const [totalItem, setTotalItem] = useState<number | null>(); |
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(() => { | ||
getLogin(); |
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.
이미 로그인된 사용자인지 확인하는 로직이 추가되면 좋겠네요! 불필요한 로그인 시도를 방지할 수 있을 것 같아요 👍
요구사항
기본
상품 등록 페이지
상품 상세 페이지
주요 변경사항
스크린샷
멘토에게
그냥 여러 커스텀훅으로 분리를 하는게 나을까요??