Skip to content
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 #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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
미완성🫠 죄송합니다..
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants