-
Notifications
You must be signed in to change notification settings - Fork 26
[김참솔] Sprint9 #124
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
[김참솔] Sprint9 #124
The head ref may contain hidden characters: "Next-\uAE40\uCC38\uC194-sprint9"
Conversation
|
스프리트 미션 하시느라 수고 많으셨어요. |
렌더링 방식 결정 질문
유경험자셔서 오히려 더 혼동이 있으신 것 같아요. 말씀주신대로 해당 미션은 단순해서 별로 차이가 없을 것이긴 하지만 저였다면 SSR로 구현했을 것 같아요. 좀 더 규모를 확장해서 100만 유저를 보유한 어플리케이션의 "마이 페이지"로 예시를 들어보면 어떨까요? 만약 저였다면 SSR + CSR로 만들었을거예요. 지금 정말 좋은 것은 참솔님은 이미 ISR과 SSR을 완벽히 이해했다는 점입니다. 👏 이런 생각도 해볼 수 있을 것 같네요. vs 그럼 다음과 같이 비교해볼 수 있을 것 같아요. 결국 적절한 비용에 대한 저울질 싸움이군요 🤣 |
|
Font 사용 질문
구글 폰트나 네이버 폰트에서 제공(외부제공자)하는 CDN을 통해서 폰트를 불러오는 것이 질문이라면
만약 그럼 결국 규모가 좀 크고 여러 앱(마이크로 서비스 아키텍쳐 같은)들이 같은 폰트를 불러와야 되는 상황이라면 자체 cdn에 |
| const BUTTON_TYPE = Object.freeze({ | ||
| add: "add", | ||
| edit: "edit", | ||
| delete: "delete", | ||
| }); |
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.
오우... Object.freeze라니. ㄷㄷ 꼼꼼하시군요? 👍
어라 근데 왜 타입스크립트는 안사용하셨나요? 🤔
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.
강의가 JavaScript로 진행되어서 별 생각 없이 이어지는 미션도 JavaScript를 사용했어요 ㅎㅎ.. 미션 10은 TypeScript로 바꾼 다음 진행할 예정입니다!
| <meta | ||
| name="description" | ||
| content="A productivity app to help you get things done" | ||
| /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1" /> |
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.
굿굿. meta도 잊지 않고 잘 작성 하셨네요 👍
| const className = { | ||
| [BUTTON_TYPE.add]: `${styles.button} ${styles.add}`, | ||
| [BUTTON_TYPE.edit]: `${styles.button} ${styles.edit}`, | ||
| [BUTTON_TYPE.delete]: `${styles.button} ${styles.delete}`, | ||
| }; | ||
|
|
||
| const leadingIcon = { | ||
| [BUTTON_TYPE.add]: "/icons/ic-plus.svg", | ||
| [BUTTON_TYPE.edit]: "/icons/ic-check.svg", | ||
| [BUTTON_TYPE.delete]: "/icons/ic-xmark-white.svg", | ||
| }; | ||
|
|
||
| function Button({ children, type = BUTTON_TYPE.add, ...props }) { | ||
| return ( | ||
| <button className={className[type]} {...props}> | ||
| <div className={styles.trailingIcon}> | ||
| <img src={leadingIcon[type]} alt={type} /> | ||
| </div> | ||
| {children} | ||
| </button> | ||
| ); | ||
| } |
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.
크으 공통 컴포넌트가 참 깔끔하네요 👍
다만, props에 type이라는 이름 보다는 color(primary, secondary, warning 등)이라고 지을 수도 있었겠네요.
...
라고 작성하려 하였으나 방금 디자인 문서 보고 오니까 디자이너가 정의해준 대로 하셨던거군요 ! 😅😅
| function colorVariable(name, shade) { | ||
| return `var(--color-${name}-${Math.max(100, Math.min(900, shade))})`; | ||
| } |
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.
크으.. 여기서도 꼼꼼함이 돋보이는군요.
string은 참 다루기 어려워요. 오타 하나라도 나면 에러가 발생하는 것도 아니고..
이렇게 함수로 만들어두면 휴먼에러 발생률이 현저히 줄겠네요 👍👍
좋은 아이디어입니다 !
| function TodoLabel({ done }) { | ||
| let className = styles.todoLabel; | ||
| if (done) { | ||
| className += ` ${styles.done}`; | ||
| } | ||
|
|
||
| return <span className={className}>{done ? "DONE" : "TO DO"}</span>; | ||
| } |
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 colorMap = {
success: styles.success,
warning: styles.warning,
error: styles.error,
info: styles.info,
};
function Label({ status = "info", children }) {
const baseClass = styles.label;
const statusClass = colorMap[status] || "";
const className = `${baseClass} ${statusClass}`.trim();
return <span className={className}>{children}</span>;
}위 제안드린 코드는 디자인에 명시된 프로퍼티는 아니지만 핵심은 "컬러를 결정짓는 props"와 "컨텐츠"를 결정짓는 props를 구분하면 어떨까 ! 라는 제안입니다 😉😉
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.
크으 ~ 유용하게 쓰시는군요 😂
훌륭합니다. 직접 http client도 만드시고 👍👍👍
| export async function getTodos() { | ||
| try { | ||
| const client = new Client(); | ||
| const items = await client.get("items"); | ||
| return items; | ||
| } catch (error) { | ||
| return []; | ||
| } | ||
| } |
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 async function getTodos() { | |
| try { | |
| const client = new Client(); | |
| const items = await client.get("items"); | |
| return items; | |
| } catch (error) { | |
| return []; | |
| } | |
| } | |
| export async function getTodos() { | |
| try { | |
| const client = new Client(); | |
| const items = await client.get("items"); | |
| return items; | |
| } catch (error) { | |
| console.error(error?.data?.message ? error.data.message : "Unknown error"); // 예시입니다 ! | |
| throw error; | |
| } | |
| } |
만약 에러가 발생했다면 해당 api 함수에서 해야 할 에러 처리(로깅과 같은)를 하고 호출부에 에러를 알리는 것이 어떨까 싶습니다 !
그리고 호출부에서 에러가 발생한다면 어떻게 사용자에게 출력할 것인지 결정해볼 수 있겠네요 😉
|
미션 수행하시느라 수고하셨습니다 참솔님 ~~!!! 질문도 참 재미있는 질문으로 느껴졌습니다. 답변드리고 싶어서 시간가는 줄 모르고 작성한 것 같아요 😏 역량은 충분하시니 참솔님은 수료 후 곧바로 원하시는 길을 빠르게 가실 수 있을거라 생각됩니다 👍 |

요구사항
기본
심화
주요 변경사항
스크린샷
멘토에게
getServerSideProps()함수를 추가해서 SSR 방식으로 렌더링되도록 구현했습니다.<Portal>component를 구현했습니다.<div id="portal"></div>를_document.js에 추가했습니다.<div>tag는npm run dev를 실행했을 때는 나타나지 않다가,npm run build및npm run start를 실행했을 때만 나타나고 정상 동작합니다._document.js에 추가한 요소가 왜 HTML에 추가되지 않는건가요? 그리고, 개발모드에서도<div id="portal">요소가 HTML에 추가되려면 어떻게 수정해야 할까요?<link>로 추가@font-family로 추가