컴포넌트 다시 생각하기

김윤진·2022년 4월 24일
1

React

목록 보기
2/13
post-custom-banner

reference
https://www.youtube.com/watch?v=HYgKBvLr49c


React 컴포넌트 의존성

리액트 컴포넌트를 만들기 위해 import를 통해 가져올 수 있는 의존성에는

  • 스타일 (내 코드 안)

    	컴포넌트의 CSS 스타일
  • 로직 (내 코드 안)

    	UI를 조작에 필요한 커스텀 로직
  • 전역 상태 (내 코드 안)

    	현재 UI를 표현하기 위해 유저의 액션에 의해 초래된 상태
  • 리모트 데이터 스키마 (내 코드 바깥)

    	API 서버에서 내려주는 데이터의 모양



비슷한 관심사라면 함께 두어야 한다


로직과 스타일을 Co-location

styled-component를 사용함으로 한 파일에서 로직과 스타일을 함께 둘 수 있다

리모트 데이터 스키마와의 의존성

props를 통해 데이터를 받아오는 것이 아닌 
props에서는 ID만 받아서 해당 컴포넌트에서 데이터 저장소와 통신을 한다



데이터를 ID 기반으로 정리하기

ID 기반으로 데이터를 정리하는 것을 Normlization, 데이터 정규화라고 한다
데이터 정규화를 도와주는 패키지

yarn add normalizr


ID 기반으로 데이터를 가져오는 형태는 숨은 의존성이 생긴다
모델을 상위에서 정확히 알고 있어야 한다는 것이다

이 의존성을 느슨하게 하기 위해
Global ID 또는 Node ID
도메인 내에서 유일성을 갖는 ID 체계



의존한다면 그대로 드러내기

User 필드

  • name
  • email
  • image (Image 모델에 thumbnailUrl을 의존하고 있다)

Image 필드

  • thumbnailUrl

👎

interface Props {
  thumbnailUrl: string
  name: string
  email: string
}

👍

interface Props {
  user: {
    name: string
    email: string
    image: {
      thumbnailUrl: string
    }
  }
}

한 컴포넌트에서 여러 모델(user, image)의 정보를 표현하고 있는 것은 관심사 분리가 잘 되지 않았다는 신호이다

모델을 분리하더라도

interface Props {
  user: {
    name: string
    email: string
    image: {
      thumbnailUrl: string
    }
  }
}

interface Props {
  image: {
    thumbnailUrl: string
  }
}

상위 컴포넌트가 하위 컴포넌트의 모양을 정확히 맞춰줘야 해서 의존성이 늘어난다

Gloal ID를 통해 컴포넌트간의 의존성을 느슨하게 만들 수 있다

interface UserCardProps {
  userId: string 
}

const user = useNode({
  on: 'User'm
  fields: {
    name: true,
    email: true,
    image: true,
  }
}, props.userId)

interface AvatarProps {
  imageId: string 
}

const image = useNode({
   on: 'Image',
   fields: {
      thumbnailUrl: true
   }
}, props.imageId)



모델을 기준으로 컴포넌트 분리하기

우리의 서비스는 끊임없이 변화되면서도 유저에게는 일관된 경험을 제공해야 한다.
유저가 생각하는 일관된 경험은 모델을 기반으로 정렬할 수 있다

같은 모델을 의존하는 컴포넌트: 재사용

다른 모델을 의존하는 컴포넌트: 분리

Items.map((item) => {
  switch (item.__typename) {
    case 'Atricle':
      return <CardAtricle articleId={item.id} />
    case 'BizPost':
      return <CardBizPost articleId={item.id} />
    default:
      retrun null
  }
}
post-custom-banner

0개의 댓글