[남숙희] Week8,11#335
Conversation
soonoo
left a comment
There was a problem hiding this comment.
부족한 설명 들어주시느라(..) 힘드셨을텐데... 파트2도 고생 많으셨습니다!
남은 스프린트 기간도 힘내서 잘 마무리하시길 응원하겠습니다 👍
| <div | ||
| style={{ backgroundImage: `url(${imageSource ?? DEFAULT_IMAGE})` }} | ||
| className={cx("container", { zoomin: isZoomedIn })} | ||
| // alt={alt} |
There was a problem hiding this comment.
아! alt 대신 title로 대체하면 되겠군요!
title={alt} 하니까 에러 안납니다!
There was a problem hiding this comment.
모종의 이유로 파일 내용에 뭔가 문제가 생긴 것 같습니다.
2번째 라인을 아래와 같이 수정하니 일단은 잘 렌더링됩니다. (다른 텍스트 파일 열듯 코드 에디터로 svg 파일을 열 수 있습니다.)
<g id="close">There was a problem hiding this comment.
엇, 왜 가 들어가있을까요?! 멘토님 말씀대로 수정하니까 잘 나옵니다!
| export const getElapsedTime = (createdAt) => { | ||
| const now = new Date(); | ||
| const createdAtDate = new Date(createdAt); | ||
| export const getElapsedTime = (createdAt: string): string => { |
There was a problem hiding this comment.
함수 인자와 본문에 타입 시스템을 잘 적용해주셨네요 👍
다만 타입스크립트는 런타임에서의 타입 안정성까지는 보장해주지 않습니다.
createdAt은 API로부터 전달받은 값이니 유효하지 않은 형태의 문자열일 가능성은 낮지만, date-fns 라이브러리의 isValid 함수를 이용해서 값의 유효성을 체크해준다면 더욱 견고한 코드가 되겠네요!
간단한 예시:
import { isValie } from "date-fns";
export const getElapsedTime = (createdAt: string): string => {
if (!isValid(createdAt)) {
return 0;
// 혹은 throw Error 등의 적절한 처리
}
}There was a problem hiding this comment.
if (!isValid(createdAt)) {
throw new Error('유효한 날짜 데이터가 아닙니다.')
}
이렇게 처리해보았습니다! 감사합니다!
| imageSource: string; | ||
| alt: string; |
There was a problem hiding this comment.
부모로부터 전달받아서 가공 없이 그대로 하위 컴포넌트의 img 태그로 전달하는 속성들이 Props에 포함되어 있는데요,
아래와 같이 img 태그의 속성들을 imgProp이라는 이름의 프로퍼티에 모아두면, img 태그에 전달하는 속성이라는 점이 더 잘 드러나고, 속성이 추가될 때마다 Props를 수정해줄 필요가 없습니다.
// Props를 아래와 같이 선언
type Props = {
url: string;
imgProp: ImgHTMLAttributes<HTMLImageElement>;
// 이하 생략
}
// imgProp을 CardImage에 그대로 전달
<CardImage
imgProp={prop.imgProp}
isZoomedIn={isHovered}
/>
// CardImage 컴포넌트에서는 spread 연산자를 이용해 img 태그에 그대로 전달
<img
{...prop.imgProp}
/>There was a problem hiding this comment.
오 ImgHTMLAttributes이런 것도 있군요! 감사합니다!
| modalOption: string; | ||
| selectedCardUrl: string; | ||
| setVisibleModal: React.Dispatch<React.SetStateAction<boolean>>; | ||
| folders: any; |
There was a problem hiding this comment.
말씀하신대로 API의 응답 구조를 하나하나 작성하는건 굉장히 성가신 일입니다. (ㅠㅠ)
완벽한 해결책은 아니지만, 아래 방법으로 작업 시간을 조금은 단축할 수는 있습니다.
- 브라우저 개발자 도구 등의 도움을 받아 아래와 같은 API 응답 샘플을 json 형태로 준비한다.
{
"data": [
{
"id": 14,
"created_at": "2023-06-04T20:59:39.293024+00:00",
"name": "⭐️ 즐겨찾기",
"user_id": 1,
"favorite": true,
"link": {
"count": 0
}
}
]
}-
https://transform.tools/json-to-typescript 에 접속 후 화면 좌측에 위치한 에디터에 1번의 json 문자열을 붙여 넣는다.
(유효한 형태의 json 문자열이어야 함. 컴마, 따옴표 등의 위치에 주의) -
우측에 출력되는 타입스크립트 인터페이스를 복사해서 적절히 수정 및 사용한다.
export interface Root {
data: Daum[]
}
export interface Daum {
id: number
created_at: string
name: string
user_id: number
favorite: boolean
link: Link
}
export interface Link {
count: number
}혹은 OpenAPI 스펙으로부터 타입 명세를 자동으로 생성해주는 도구를 기억해두셨다가, 추후 타입 시스템과 코드 작성에 익숙해지셨을 때 다시 한번 살펴보시는 것도 좋겠습니다.
예시: openapi-typescript-codegen
There was a problem hiding this comment.
우와... 이거 엄청 편하네요!!!! 좋은 에디터를 알려주셔서 감사합니다!
요구사항
기본
심화
주요 변경사항
스크린샷
멘토에게