-
Notifications
You must be signed in to change notification settings - Fork 38
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-2 #266
The head ref may contain hidden characters: "Next-\uACE0\uC6A9\uBE48-sprint10"
[고용빈] Sprint10-2 #266
Conversation
const nextConfig = { | ||
reactStrictMode: true, | ||
images: { | ||
domains: ['sprint-fe-project.s3.ap-northeast-2.amazonaws.com'], | ||
domains: [ | ||
"sprint-fe-project.s3.ap-northeast-2.amazonaws.com", | ||
"example.com", | ||
], | ||
}, | ||
} | ||
}; | ||
|
||
module.exports = nextConfig | ||
module.exports = nextConfig; |
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.
원래 서버에서 받아오는 이미지들을 사용할 때, example.com
이 없어도 잘 됐었는데 갑자기 에러가 나더니 추가해주니까 괜찮아졌습니다..!
example.com
을 추가하고 동작은 잘 하지만 터미널에 위와 같은 404 에러가 계속 발생합니다.
next/image 공식 문서처럼 해결 해봤는데도 잘 안돼서 질문 드립니다!
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.
next/image
컴포넌트를 사용하면 Next.js에서 제공하는 특별한 이미지 최적화 기법을 적용할 수 있습니다(사이즈별로 크기가 다른 이미지를 자동으로 생성해줌).
- 근데
domains
설정은, 저기 설정된 도메인들에 대해서만next/image
의 이미지 최적화를 실행하겠다는 뜻입니다. 따라서 저기에 아무것도 지정해주지 않아도 제대로 작동해야 합니다. ..인줄 알았는데remotePatterns
에 반드시 도메인을 지정하던가,next/image
컴포넌트 말고 그냥<img>
요소를 이용해야 겠네요. 굳이 외부 이미지들에 대해서 최적화를 실행할 필요는 없어 보여서 저 이미지들은 그냥<img>
요소를 사용하는 게 더 나아 보입니다. - Next 14버전 부터는
domains
값은 deprecated 되었고,remotePatterns
값으로 대체 되었습니다.
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.
거의 완벽하게 피드백 드린 걸 반영해주셨네요! 😄
특히 커밋 메시지도 읽기 쉽게 작업별로 구분 되어 있어서 상당히 인상적이었습니다.
고생 많으셨습니다! 👍
SSG와 SSR에 대한 말씀을 짧게 드리면,
Next에서 모든 페이지는 별도의 SSR 관련 로직을 사용하지 않는다면 SSG로 처리됩니다. 따라서 지금 작성하신 모든 페이지는 HTML을 사전에 생성해두는 SSG를 사용하신 것이나 다름이 없습니다.
SSR은 특정 페이지에 대한 요청이 왔을 때, 그 페이지에서 호출해야 할 API를 사용자 브라우저에서 호출하는 게 아니라 프론트엔드 서버에서 직접 호출해서 완성된 HTML을 만들고 그걸 요청에 대한 응답으로 반환하는 것입니다. 사실 모든 페이지에서 SSR을 적용하고자 하면 다 할 수 있지만, 제품 상세 페이지와 같은 상세 페이지에 적용했을 때 그나마 제일 유용하다고 생각합니다.
(사실 개인적인 생각은, 학습하신 것처럼 axios나 fetch를 사용하는 건 모두 클라이언트 사이드(브라우저)에서 데이터를 요청하는 것이기도 하고, 대부분의 경우엔 이걸로도 충분해서 SSR를 적용하는 게 더 이득인 경우는 많지 않다고 생각합니다)
@@ -0,0 +1 @@ | |||
NEXT_PUBLIC_API_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.
👍
@@ -1,21 +1,60 @@ | |||
import { useRef, useState } from "react"; | |||
import Image from "next/image"; | |||
import styles from "./styles.module.scss"; |
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.
이 파일도 같은 디렉토리 내에 있긴 하지만 절대 경로로 바뀌면 더 좋을 것 같네요.
|
||
function AddBoard() { | ||
const fileInputRef = useRef<HTMLInputElement | null>(null); | ||
const [titleInputValue, setTitleInputValue] = useState(""); | ||
const [contentTextAreaValue, setContentTextAreaValue] = useState(""); |
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.
이름에 TextArea
라는 표현은 없어도 될 것 같습니다. 이 state에 담을 내용이 content
라는 게 중요한 거지, 내용이 어떤 곳에 담길지는 이름에 없어도 될 것 같습니다. 이 필드가 textarea가 아니라 select나 일반 input으로 바뀐다면 이 이름도 변경이 필요하기 때문입니다. 위에 titleInputValue
도 마찬가지입니다. 어떻게 보면 value
라는 글자도 없어도 될 것 같긴 하네요
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.
아직도 변수명을 짓는 게 어렵네요..! 무조건 구체적이게 짓는 게 좋다고 생각했는데, 한 번 더 생각하고 지어야겠습니다 ㅎㅎ 감사합니다!
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.
이게 각각의 코멘트를 나타내는 컴포넌트면, CommentItem
같은 이름으로 바꿔도 좋을 것 같습니다. 전체 코멘트 리스트를 나타내는 컴포넌트라고 혼동할 여지가 있습니다. 이렇게 바꾸면
Comment
라는 타입을 CommentType
이라는 이름으로 바꾸지 않아도 되어서 더 좋을 것 같아요.
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.
감사합니다! 컴포넌트 이름을 바꾸니까 타입을 CommentType
이라고 굳이 선언하지 않아도 되네요! 변수명과 마찬가지로 컴포넌트명 짓는 것도 많은 도움 주셔서 감사합니다 ㅎㅎ
const [comments, setComments] = useState<Article[]>([]); | ||
const router = useRouter(); | ||
const [comments, setComments] = useState<CommentType[]>([]); | ||
const router: any = useRouter(); |
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.
이젠 any
를 제거해도 타입 오류가 안 뜰 것 같은데 아닌가요?
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.
여전히 발생하고 있습니다 ㅜ 말씀해주신 방법들 적용해봤는데, any
말고는 해결이 안되네요...
@@ -32,15 +33,11 @@ function BoardsDetail() { | |||
useEffect(() => { | |||
const fetchArticle = async () => { | |||
try { | |||
const fetchedArticle = await getArticleById(id); | |||
const fetchedArticle = await getArticleById(Number(id)); |
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.
id
를 굳이 number로 안 바꾸고 string으로만 처리해도 될 것 같아요. 아마 이 파일 23행에서
const { id } = router.query;
로 쿼리 스트링에서 id
를 가져오면 id
타입이 string | string[] | undefined
라고 나올텐데, undefined
면 애초에 오류 메시지가 표시되어야 하고,
string[]
일 땐 첫 번째 index만 가져와도 될 것 같네요. ex)
ex) 24행에 다음과 같이 추가
const articleId = Array.isArray(id) ? id[0] : id
사실 데이터 구조를 설계할 때 id가 항상 number인 것은 아닙니다. 알파벳과 숫자가 섞인 string이 id가 되는 경우도 흔합니다.
</div> | ||
</div> | ||
|
||
<div className={styles["mobile-dropdown"]}> |
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.
js 로직이 없어지니까 훨씬 나아졌네요 👍
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.
신세계입니다 ㅎㅎ
@@ -45,6 +45,7 @@ select { | |||
} | |||
html { | |||
box-sizing: border-box; | |||
font-family: Pretendard, sans-serif; |
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.
Pretendard 레포지토리에 나와 있는 font-family
설정법을 확인해보세요.
특히 어디서든 동일한 환경을 가지고자 한다면 아래와 같은 font-family 구성을 추천합니다.
라고 써있는 부분입니다.
https://github.com/orioncactus/pretendard?tab=readme-ov-file#font-family
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.
왠지 적용이 안되더라구요! 안되는 거 같았을 때 설정 방법을 좀 더 찾아봤어야 하는데..! 말씀해 주신 방법대로 수정하니까 잘 되네요 ㅎㅎ 감사합니다!!!
.then((response) => response.data); | ||
}; | ||
|
||
export const getArticleById = (articleId: number): Promise<Article> => { |
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.
여기에 리턴 타입으로 : Promise<Article>
을 지정해주지 않아도 됩니다. get
옆에 제너릭으로 넣어주면 됩니다.
return axiosInstance
.get<Article>(`/articles/${articleId}`)
.then((response) => response.data);
그리고 저번 멘토링 시간에 말씀드렸던 것처럼
.then((response) => response.data);
자체가 없는 게(그러니까 response
에서 굳이 data
를 빼서 반환하지 않는 게) 범용성이 더 높아질 것 같습니다.
): Promise<ApiResponse<Comment>> => { | ||
return axiosInstance | ||
.get(`/articles/${articleId}/comments`, { | ||
params: { limit }, |
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.
params
도 잘 사용하셨네요 👍
요구사항
기본
주요 변경사항
스크린샷
멘토에게