Skip to content

[남숙희] Week8,11#335

Open
sooki88 wants to merge 8 commits intocodeit-bootcamp-frontend:part3-남숙희from
sooki88:week8
Open

[남숙희] Week8,11#335
sooki88 wants to merge 8 commits intocodeit-bootcamp-frontend:part3-남숙희from
sooki88:week8

Conversation

@sooki88
Copy link
Copy Markdown
Collaborator

@sooki88 sooki88 commented Jan 2, 2024

요구사항

기본

  • 폴더 페이지에 필요한 “폴더 이름 변경”, “폴더 추가”, “폴더 공유”, “폴더 삭제”, “링크 삭제”, “폴더에 추가” 모달을 만들어 주세요.
  • “폴더 공유” 모달의 기능은 클릭시 ‘{호스트 주소}/shared?user={현재 로그인 중인 유저 ID}&folder={현재 열려있는 폴더}’ 로 접속 가능한 주소를 공유 또는 클립보드에 복사 가능하게 해주세요.
  • 팀내 2 ~ 3명이 짝을 지어 페어프로그래밍으로 여러 모달을 만들 때 사용할 모달 컴포넌트를 만들어 주세요.
  • 카드에 있는 케밥 버튼을 클릭할 경우 보여야 할 팝오버를 만들어 주세요.
  • TypeScript를 활용해 프로젝트의 필요한 곳에 타입을 명시해 주세요.
  • ‘/shared’, ‘/folder’ 페이지에 현재 폴더에서 검색어가 포함된 링크를 찾을 수 있는 링크 검색 기능을 만들어 주세요.

심화

  • 폴더 페이지에 상단에 있는 링크 추가하기 input이 화면에서 가려질 때 최하단에 고정해 주세요.

주요 변경사항

  • week7 템플릿을 사용했습니다.

스크린샷

스크린샷 2024-01-02 오후 1 33 07 스크린샷 2024-01-02 오후 1 34 25

멘토에게

  • week7 템플릿을 사용해서 typescript로 변환했는데 중간에 어려운 부분은 any로 처리한 것도 있습니다. 특히 api 데이터 받아올때 [{객체:{또객체: 값}},{},...] 이런 구조의 경우 type 지정이 어렵습니다.
  • 케밥 버튼 관련한 모달이 보이는 것까지 만들었습니다!
  • Modal.tsx 이미지 임포트가 잘 안됩니다! src에 @types 폴더 만들고 custom.d.ts까지 만들어서 svg 선언해줘서 에러는 안나는데 이미지가 제대로 안나옵니다ㅜ
  • 브랜치 comfilct 문제는 해결 못했습니다ㅜ
  • typescript로 변환하는데 시간이 많이 소요돼서 미션을 조금밖에 성공 못해서 아쉽습니다! 그동안 멘토링하시면서 설명하기 난감하거나 복잡한 것들도 많았을데 열심히 찾아봐주시고 침착하게 잘 설명해주셔서 덕분에 2주차까지 포기안하고 살아남을 수 있었습니다! 감사합니다!

@sooki88 sooki88 changed the title Week8 [남숙희] Week8,11 Jan 2, 2024
@sooki88 sooki88 requested a review from soonoo27 January 2, 2024 04:45
@sooki88 sooki88 added the 미완성 죄송합니다... label Jan 2, 2024
Copy link
Copy Markdown

@soonoo soonoo left a comment

Choose a reason for hiding this comment

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

부족한 설명 들어주시느라(..) 힘드셨을텐데... 파트2도 고생 많으셨습니다!
남은 스프린트 기간도 힘내서 잘 마무리하시길 응원하겠습니다 👍

Comment thread src/sharing/ui-card-image/CardImage.tsx Outdated
<div
style={{ backgroundImage: `url(${imageSource ?? DEFAULT_IMAGE})` }}
className={cx("container", { zoomin: isZoomedIn })}
// alt={alt}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

alt는 img 태그의 속성이므로 출력되는 에러 메시지가 잘못된 것은 아닙니다.
div 태그를 사용하신다면 alt 속성과 유사한 역할을 하는 title 속성을 사용할 수 있습니다.

<div
    title={title}
/>

alt 속성은 img 태그의 내용이 화면에 표시되지 않을 때 노출할 대체(alternate) 텍스트를, title 속성은 말 그대로 해당 요소의 제목을 나타내며 주로 마우스롤 호버했을 때 툴팁을 나타내는 용도로 사용된다고 합니다.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

아! alt 대신 title로 대체하면 되겠군요!
title={alt} 하니까 에러 안납니다!

Comment thread src/assets/close.svg
Copy link
Copy Markdown

@soonoo soonoo Jan 3, 2024

Choose a reason for hiding this comment

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

모종의 이유로 파일 내용에 뭔가 문제가 생긴 것 같습니다.
2번째 라인을 아래와 같이 수정하니 일단은 잘 렌더링됩니다. (다른 텍스트 파일 열듯 코드 에디터로 svg 파일을 열 수 있습니다.)

<g id="close">

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

엇, 왜 &#8가 들어가있을까요?! 멘토님 말씀대로 수정하니까 잘 나옵니다!

export const getElapsedTime = (createdAt) => {
const now = new Date();
const createdAtDate = new Date(createdAt);
export const getElapsedTime = (createdAt: string): string => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

함수 인자와 본문에 타입 시스템을 잘 적용해주셨네요 👍
다만 타입스크립트는 런타임에서의 타입 안정성까지는 보장해주지 않습니다.

createdAt은 API로부터 전달받은 값이니 유효하지 않은 형태의 문자열일 가능성은 낮지만, date-fns 라이브러리의 isValid 함수를 이용해서 값의 유효성을 체크해준다면 더욱 견고한 코드가 되겠네요!

간단한 예시:

import { isValie } from "date-fns";
export const getElapsedTime = (createdAt: string): string => {
  if (!isValid(createdAt)) {
    return 0;
    // 혹은 throw Error 등의 적절한 처리
  }
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

if (!isValid(createdAt)) {
throw new Error('유효한 날짜 데이터가 아닙니다.')
}

이렇게 처리해보았습니다! 감사합니다!

Comment on lines +13 to +14
imageSource: string;
alt: string;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

부모로부터 전달받아서 가공 없이 그대로 하위 컴포넌트의 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}
/>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

오 ImgHTMLAttributes이런 것도 있군요! 감사합니다!

modalOption: string;
selectedCardUrl: string;
setVisibleModal: React.Dispatch<React.SetStateAction<boolean>>;
folders: any;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

말씀하신대로 API의 응답 구조를 하나하나 작성하는건 굉장히 성가신 일입니다. (ㅠㅠ)
완벽한 해결책은 아니지만, 아래 방법으로 작업 시간을 조금은 단축할 수는 있습니다.

  1. 브라우저 개발자 도구 등의 도움을 받아 아래와 같은 API 응답 샘플을 json 형태로 준비한다.
{
    "data": [
        {
            "id": 14,
            "created_at": "2023-06-04T20:59:39.293024+00:00",
            "name": "⭐️ 즐겨찾기",
            "user_id": 1,
            "favorite": true,
            "link": {
                "count": 0
            }
        }
    ]
}
  1. https://transform.tools/json-to-typescript 에 접속 후 화면 좌측에 위치한 에디터에 1번의 json 문자열을 붙여 넣는다.
    (유효한 형태의 json 문자열이어야 함. 컴마, 따옴표 등의 위치에 주의)

  2. 우측에 출력되는 타입스크립트 인터페이스를 복사해서 적절히 수정 및 사용한다.

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

Copy link
Copy Markdown
Collaborator Author

@sooki88 sooki88 Jan 5, 2024

Choose a reason for hiding this comment

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

우와... 이거 엄청 편하네요!!!! 좋은 에디터를 알려주셔서 감사합니다!

@sooki88 sooki88 requested review from soonoo27 and removed request for soonoo27 January 6, 2024 22:27
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.

3 participants