Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[최윤석] Sprint10 #732

Conversation

greenyun2
Copy link
Collaborator

요구사항

기본

  • 게시글 등록 페이지 주소는 “/addboard” 입니다.

  • 게시판 이미지는 최대 한개 업로드가 가능합니다.

  • 각 input의 placeholder 값을 정확히 입력해주세요.

  • 이미지를 제외하고 input 에 모든 값을 입력하면 ‘등록' 버튼이 활성화 됩니다

  • 게시글 상세 페이지 주소는 “/board/{id}” 입니다.

  • 댓글 input 값을 입력하면 ‘등록' 버튼이 활성화 됩니다.

  • 자유게시판 페이지에서 게시글을 누르면 게시물 상세 페이지로 이동합니다.

  • 게시글 상세 페이지 주소는 “/board/{id}” 입니다.

  • 댓글 input 값을 입력하면 ‘등록' 버튼이 활성화 됩니다.

심화

  • [x]
  • []

주요 변경사항

스크린샷

image
image

멘토에게

  • 미완성입니다. addboard 페이지 스타일링 밖에 못했습니다
  • 다음에 기능 추가해서 올리겠습니다

@greenyun2 greenyun2 changed the title Next.js 최윤석 sprint10 [최윤석] Sprint10 Jul 19, 2024
@greenyun2 greenyun2 requested a review from kiJu2 July 19, 2024 12:49
@greenyun2 greenyun2 added the 미완성🫠 죄송합니다.. label Jul 19, 2024
@kiJu2
Copy link
Collaborator

kiJu2 commented Jul 22, 2024

수고 하셨습니다 ! 스프리트 미션 하시느라 정말 수고 많으셨어요.
학습에 도움 되실 수 있게 꼼꼼히 리뷰 하도록 해보겠습니다.

@kiJu2
Copy link
Collaborator

kiJu2 commented Jul 22, 2024

미완성입니다. addboard 페이지 스타일링 밖에 못했습니다

괜찮습니다 ! 완성보다 중요한 것은 꾸준함이지요 =)

다음에 기능 추가해서 올리겠습니다

넵넵 ~!

Comment on lines +17 to +18
<Image src={medal} width={16} height={16} alt='메달 아이콘' />
<span>Best</span>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단순 장식용으로 있을 경우 ""로 나타낼 수 있습니다 !

Suggested change
<Image src={medal} width={16} height={16} alt='메달 아이콘' />
<span>Best</span>
<Image src={medal} width={16} height={16} alt="" />
<span>Best</span>

장식 이미지는 페이지 콘텐츠에 정보를 추가하지 않습니다. 예를 들어, 이미지에서 제공하는 정보는 인접한 텍스트를 사용하여 이미 제공될 수도 있고, 웹 사이트를 시각적으로 더욱 매력적으로 만들기 위해 이미지가 포함될 수도 있습니다.

이러한 경우 스크린 리더와 같은 보조 기술에서 무시할 수 있도록 null(빈) alt텍스트를 제공해야 합니다( ). alt=""이러한 유형의 이미지에 대한 텍스트 값은 화면 판독기 출력에 청각적 혼란을 추가하거나 주제가 인접한 텍스트의 주제와 다른 경우 사용자의 주의를 산만하게 할 수 있습니다. 속성 을 생략하는 alt것도 옵션이 아닙니다. 속성이 제공되지 않으면 일부 화면 판독기가 이미지의 파일 이름을 대신 알려주기 때문입니다.

Decorative Images

Comment on lines +6 to +12
export default function BestPostArticles({
title,
image,
likeCount,
updatedAt,
writer,
}) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳굳 UI 컴포넌트군요 ?

따로 components/ui로 파일을 분류해도 되겠어요. 😊

Comment on lines +3 to +5
const instance = axios.create({
baseURL: "https://panda-market-api.vercel.app",
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳굳 ~! instance를 따로 생성해두셨군요 !

import axios from "axios";

const instance = axios.create({
baseURL: "https://panda-market-api.vercel.app",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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을 변경할 수 있으며, 코드의 가독성과 유지보수성도 개선됩니다.

실제 코드 응용과 관련해서는 다음 한글 아티클을 참고해보세요! => 보러가기

useEffect(() => {
async function getBestArticles() {
try {
const res = await axios.get("articles?page=1&pageSize=3&orderBy=like");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

보통 api 함수들은 따로 파일을 분류하여 사용하는게 일반적입니다 ! 😊

프로젝트에서는 API 호출 로직을 별도의 파일로 분리하여 관리하는 것이 일반적이예요. 이렇게 하면 컴포넌트, 페이지, 훅 등 어디든 사용될 수 있겠죠?😊
코드의 재사용성을 높이고, 유지보수가 쉬워질 수 있습니다 ! API 함수를 모듈화하여 사용하면 코드가 더 깔끔하고 읽기 쉬워집니다. 다음은 프로젝트의 디렉토리 구조와 API 함수 예제입니다:

// src/services/apis/best-articles.api.ts (예시입니다 !)
export const getBestArticles = async () => {
	try {
		const { data } = await axios.get('articles?page=1&pageSize=3&orderBy=like');
		return data;
	} catch(error) {
		throw error;
	}
};

Comment on lines +8 to +10
export default function Button({ children }: ButtonProps) {
return <button>{children}</button>;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고 다음과 같이 컴포넌트를 작성할 수 있어요:

Suggested change
export default function Button({ children }: ButtonProps) {
return <button>{children}</button>;
}
export default function Button({ children, ...rest }: ButtonProps) {
return <button {...rest}>{children}</button>;
}

그럼 다음과 같은 코드 작성을 할 수 있을거예요:

<Button type="button" onClick={() => {}}>버튼 !</Button>

type, onClick 등의 타입들은 별도로 작성할 필요 없고 추 후 필요하더라도 수정할 필요 없으니 확장성에 유리할거예요 😊

Comment on lines +3 to +8
interface InputProps {
id: string;
type: HTMLInputTypeAttribute;
placeholder: string;
className: string;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 컴포넌트를 포함한 기본 컴포넌트들은 위 버튼처럼 타입을 지정해볼 수 있습니다 =)

Comment on lines +19 to +21
{!image ?? (
<Image src={image} width={72} height={72} alt='상품 이미지' />
)}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오잉?

이렇게 하면 imagefalsy일 때 true가 되어 ?? 연산이 안되지 않을까요?
Not(!)을 사용하면 undefined 혹은 null일 때의 상황은 없을 것 같아요.

falsy란?: 거짓 같은 값이예요. null, undefined, false, NaN, 0, -0, 0n, "" 과 같은 값들을 의미해요.

Comment on lines +13 to +25
async function getArticles() {
try {
const res = await axios.get("/articles?page=1&pageSize=6&orderBy=recent");
const nextArticles = res.data.list ?? [];
setArticles(nextArticles);
} catch (error) {
console.error(error);
}
}

useEffect(() => {
getArticles();
}, []);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다음과 같이 useEffect 내에 선언할 수 있어요:

Suggested change
async function getArticles() {
try {
const res = await axios.get("/articles?page=1&pageSize=6&orderBy=recent");
const nextArticles = res.data.list ?? [];
setArticles(nextArticles);
} catch (error) {
console.error(error);
}
}
useEffect(() => {
getArticles();
}, []);
useEffect(() => {
async function getArticles() {
try {
const res = await axios.get("/articles?page=1&pageSize=6&orderBy=recent");
const nextArticles = res.data.list ?? [];
setArticles(nextArticles);
} catch (error) {
console.error(error);
}
}
getArticles();
}, [setArticles]);

만약 useEffect 바깥에 선언하게 되면 리렌더링에 의한 불필요한 재선언이 될 수 있습니다 😊


export default function Document() {
return (
<Html lang="en">
<Html lang='ko'>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳굳~! 꼼꼼하시네욤 ㅎㅎㅎ

@kiJu2
Copy link
Collaborator

kiJu2 commented Jul 22, 2024

굳굳 ~! 스프린스 미션 하시느라 수고 정말 많으셨어요 윤석님.
혹시나 더 궁금하신게 있으시다면 편하게 사전 질문을 통해 질문주세요 ~! ㅎㅎㅎ

@kiJu2 kiJu2 merged commit 6f8597c into codeit-bootcamp-frontend:Next.js-최윤석 Jul 22, 2024
1 check failed
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
미완성🫠 죄송합니다..
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants