Skip to content

Conversation

@jeschun
Copy link
Collaborator

@jeschun jeschun commented Sep 21, 2025

요구사항

기본

목록 조회

  • ‘로고’ 버튼을 클릭하면 ‘/’ 페이지로 이동합니다. (새로고침)
  • 진행 중인 할 일과 완료된 할 일을 나누어 볼 수 있습니다.

할 일 추가

  • 상단 입력창에 할 일 텍스트를 입력하고 추가하기 버튼을 클릭하거나 엔터를 치면 할 일을 새로 생성합니다.

할 일 완료

  • 진행 중 할 일 항목의 왼쪽 버튼을 클릭하면 체크 표시가 되면서 완료 상태가 됩니다.
  • 완료된 할 일 항목의 왼쪽 버튼을 다시 클릭하면 체크 표시가 사라지면서 진행 중 상태가 됩니다.

심화

주요 변경사항

  • SSR을 사용했습니다.
  • 커밋에 변경사항들을 최대한 썼습니다.

스크린샷

스크린샷 2025-09-22 오전 2 57 00 스크린샷 2025-09-22 오전 3 55 24

멘토에게

  • 체크박스를 누르면 피그마 디자인처럼 만들려고 노력했는데 그게 안되서 그냥 전부 보라색으로 칠해지는걸로 바꿨습니다 어떤 코드를 추가해야 저렇게 흰색 체크로 나올 수 있을까요 구글링하면서 여러가지 시도해봤는데 시간을 너무 많이 뺏기고 잘안되서 여쭤봅니다.

  • 폴더 구조를 제 임의대로 만들었는데 이게 좋은 폴더구조인지 궁금합니다.

  • 생각보다 어려워서 강의를 많이 참고 했는데 잘하건지 궁금합니다.

  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@jeschun jeschun requested a review from kiJu2 September 21, 2025 20:13
@jeschun jeschun added 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 순한맛🐑 마음이 많이 여립니다.. and removed 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. labels Sep 21, 2025
@kiJu2
Copy link
Collaborator

kiJu2 commented Sep 23, 2025

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

@kiJu2
Copy link
Collaborator

kiJu2 commented Sep 23, 2025

https://18-sprint-mission-sprint9.vercel.app/ -----> 요거는 링크클릭해서 안되면 링크주소를 복사한 다음에 따로 주소에 붙여넣기하시면 들어가집니다 이상하게 위 링크클릭하면 안되네요...


[url](https://18-sprint-mission-sprint9.vercel.app/) 이렇게 붙여넣으시면 됩니다 ! 😉
마크다운에서 링크 삽입은 [주소에 대한 설명](http://www.google.co.kr/) 이렇게 해주시면 되세요 ~!

@kiJu2
Copy link
Collaborator

kiJu2 commented Sep 23, 2025

시행 영상 먼저 공유드립니다 !

2025-09-23.2.14.27.mov
  1. 레이아웃이 디자인 시안과 다른 것 같군요 !
    중앙 정렬된 컨테이너로 감싸져야될 것 같습니다 😉

  2. macos 환경에서 엔터를 치면 두 번 요청이 가는 오류가 있는 것 같아요 !
    해당 버그는 운영체제와 브라우저 간 발생하는 오류일 수 있어요.
    CompositionEvent를 활용해서 해결하는 방법이 있으니 참고하셔도 좋을 것 같습니다 😉

  3. 투두를 체크 시 Done으로 넘어가는 것처럼 보이기는 하나 새로고침하면 서버단에서는 적용이 되지 않은 것 같아요 !

일단 보여지는 버그는 위와 같습니다 ! 다음 미션 때 해결해보시면 좋을 것 같습니다 😊

@kiJu2
Copy link
Collaborator

kiJu2 commented Sep 23, 2025

체크박스를 누르면 피그마 디자인처럼 만들려고 노력했는데 그게 안되서 그냥 전부 보라색으로 칠해지는걸로 바꿨습니다 어떤 코드를 추가해야 저렇게 흰색 체크로 나올 수 있을까요 구글링하면서 여러가지 시도해봤는데 시간을 너무 많이 뺏기고 잘안되서 여쭤봅니다.

넵 ! 코드 리뷰 때 답변드리겠습니다 👍

폴더 구조를 제 임의대로 만들었는데 이게 좋은 폴더구조인지 궁금합니다.

확인해보겠습니다 ~!

Comment on lines +22 to +24

const idRef = useRef(0);

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
const idRef = useRef(0);

Comment on lines +8 to +16
export const getServerSideProps = async (
context: GetServerSidePropsContext
) => {
console.log(context);

const allItems = await fetchItems(1, 10);

return { props: { allItems } };
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

훌륭합니다. 🥺 SSR로 초기 데이터를 받아오셨군요 👍

중간에 console.log가 적힌걸 보니 디버깅 하시면서 개발하셨나봐요 ㅎㅎㅎ 뿌듯하네요.
다만, console.log는 틈틈히 지우시는게 좋습니다 !

아. git add 하실 때 꿀팁 하나 드리자면 스테이징 에어리어에 올릴 때 검토 한 번 할 수 있습니다 !
검토하시면서 console.log 같은거 보이면 없애버릴 수 있어요 ~

git add {path} -p 옵션

git add . -p를 사용하게 되면 변경사항을 스테이징에 올릴 때 파일 내 코드 단위로 잘라서 올릴 수 있습니다 ! 상당히 유용하므로 히스토리를 신경쓰신다면 꼭 사용해보세요 😊

어떻게 사용하지?

git add . -p

git commit -v

변경 사항을 커밋하기 전에 마지막으로 검토할 수 있습니다 !

git add -p와 git commit -v의 사용

Comment on lines +7 to +17
export async function fetchItems(page = 1, pageSize = 10): Promise<ItemData[]> {
try {
const { data } = await instance.get<ItemData[]>(`/api/${TENANT_ID}/items`, {
params: { page, pageSize },
});
return data;
} catch (err) {
console.error(err);
return [];
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

깔끔합니다 신천님 🥺🥺🥺

하나 작은 흠이 있다면 !
현재 에러가 발생하여도 호출부(컴포넌트)에서는 "정상 동작 되는 것"으로 인식하게 될 것으로 보여요.
이렇게 되면 사용자에게 네트워킹 관련 에러나 서버로부터 받은 피드백 등을 출력해주기 어려울거예요.

따라서, catch에서 throw를 해보면 어떨까요?
API 함수는 API와 관련된 예외처리(로깅 등)을 하고 throw를 던져서 호출부에서 catch할 수 있도록 만들어볼 수 있을거예요.
만약 이렇게 한다면 프로덕트에서 사용하던 toastmodal도 수월하게 사용해볼 수 있겠네요 😉

import { ItemData, DeleteData } from "./types";
import instance from "./axios";

const BASE_URL = "https://assignment-todolist-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을 변경할 수 있으며, 코드의 가독성과 유지보수성도 개선됩니다.

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

import instance from "./axios";

const BASE_URL = "https://assignment-todolist-api.vercel.app";
const TENANT_ID = "godfather";
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에 포함하여(혹은 따로 구분해도 무관 !) 환경 변수로 저장시킬 수 있겠네요 😉

Comment on lines +3 to +9
const BASE_URL = "https://assignment-todolist-api.vercel.app";

const instance = axios.create({
baseURL: BASE_URL,
headers: { "Content-Type": "application/json" },
timeout: 10000,
});
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은 필요 없는 코드였군요?

Suggested change
const BASE_URL = "https://assignment-todolist-api.vercel.app";
const instance = axios.create({
baseURL: BASE_URL,
headers: { "Content-Type": "application/json" },
timeout: 10000,
});
const BASE_URL = `process.env.NEXT_PUBLIC_BASE_URL/${process.env.NEXT_PUBLIC_TENANT_ID}`;
const instance = axios.create({
baseURL: BASE_URL,
headers: { "Content-Type": "application/json" },
timeout: 10000,
});

이렇게 설정해볼 수 있겠네요 !

Comment on lines +21 to +24
.input:checked {
background: #6d28d9;
border-color: #6d28d9;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

체크박스를 누르면 피그마 디자인처럼 만들려고 노력했는데 그게 안되서 그냥 전부 보라색으로 칠해지는걸로 바꿨습니다 어떤 코드를 추가해야 저렇게 흰색 체크로 나올 수 있을까요 구글링하면서 여러가지 시도해봤는데 시간을 너무 많이 뺏기고 잘안되서 여쭤봅니다.

엥 ? 거의 다 만드셨네요 !
::after 사용하시면 쉽게 구현할 수 있습니다 !

Suggested change
.input:checked {
background: #6d28d9;
border-color: #6d28d9;
}
.input:checked {
position: relative;
}
.input:checked::after {
content: "";
position: absolute;
top: -2px;
left: -2px;
width: 20px;
height: 20px;
background: url("/checkbox.svg") no-repeat center center;
background-size: cover;
}

위와 같이 추가하시면 현재 구조에서 가장 빠르게 적용 가능한 방법이지 않을까 싶습니다 ! 😉

@kiJu2
Copy link
Collaborator

kiJu2 commented Sep 23, 2025

미션 수행하시느라 수고하셨습니다 신천님 !
감격스러운 코드리뷰였습니다.. 성장 속도 무엇이예요 대체 ㅠㅠ
앞으로도 지금과 같은 기세로 전진합시다 ! 💪💪

@kiJu2 kiJu2 merged commit b26cdf4 into codeit-bootcamp-frontend:Next-박신천 Sep 23, 2025
@jeschun
Copy link
Collaborator Author

jeschun commented Sep 23, 2025

리뷰 감사합니다 ! 강사님 덕에 많이 배웠습니다 🙏 피드백 주신거 한번 차근차근 읽어보고 다음 미션때 적용해보도록 하겠습니다 🙂

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.

2 participants