들어가면서

짧게 쓰고 땡 칠 것이다. 3주간의 계획 보고서를 쓰냐고 야근을 했더니 피곤하다. 내일 remote 가 아니었다면 절망하고 울었을 것치다.

세상에 멋진건 많다.

라인 디자인 시스템이 있다. 문서가 잘되어 있었다는 생각이 들었다.
Material UI 도 있다. 좋다.

내 생각엔

컴포넌트가 아름답거나 둥글기가 아주 좋거나 해서가 아니다.
UI 정책 혹은 전략이 있고 그에 따라서 내려오는 컴포넌트 배치 가이드가 있어 좋다.

좌측 마진 3px, 우측 마진 9px… 지친다.

그때 그때 만들고 내일 다시 고칠 거면 가지고 오지 말자.

마치며

컴포넌트 라이브러리가 있으면 좋겠지만 의외로 HTML 에서는 다 있다.
내가 정말 필요하다고 느끼는 것은 구성에 대한 것이다.
적어도 4px 단위의 처리 정도는 있었으면 좋겠다.
그리고 UI 의 철학까지는 아니어도 일관성 그리고 그 일관성에서 나오는 직관과 편의가 함께 하길 기도해본다.

다시 잡아 올린다.

이글을 안올렸었다.
나는 요새 technical lead 로 일하고 있다. 최대한 가치 중립(?) 적인 이야기를 하다보니, 이렇게 감정 섞인 내용이 밖으로 나갔을 때 나올 수 있는 사이드 이팩트가 참 어려웠었다.

하지만 지금 아이들 친구들이 와서, 내 애매한 포지션으로 인해 스타벅스로 쫓겨나서 컴퓨터를 열고 있다.
왠만하면 회사일은 주말에 안하려고 하고 있고 알고리즘을 풀고 있는데,
사실 알고리즘을 풀면 회사 일을 잘하냐? 모르겠다.
치매 예방으로 하고 있는 것인데, 요새 이 지점에 대한 고민이 있다.
당장은 TO 가 없기에 큰 고민은 안하겠지만 어떤 것으로 검증을 해야 할지 고민이다.

아무래도 나는 DP 에는 재능이 없어서 DP 문제 앞에서 크게 울어보기도 했었다.
아는 문제라서 아는 방식으로 풀었다가 아니라는 말을 듣고 펑펑 울기도 했고 그 앞에서는 그게 아닌데 말도 못했던 적도 많다.
sub array 의 최대 값을 가져오는 문제였는데, 사실 음수 처리가 있어서 더 고려를 해야했지만 뭐 그냥 그렇게 되었던 생각이 아직도 난다.

그렇다고 해서 코딩 인터뷰때 반응이 좋았다고 해서 채용으로 이루어지지 않은 적도 많기도하고 이 애증의 부분은 지금 주제는 아니니 다시 내 마음속의 스텍에 넣어 두기로 하자.

왜 Props 가 싫었나?

아니다. 난 좋아한다. 프리젠테이션 패턴(?) 참 편하고 일 시작할 때 부터 있던 거라 참 좋다.

에를 들면

interface ItemProps { 
  name: string;
  phone: string;
  info : {
    no: string;
    dap: string;
  }
}
const List (items: Array<ItemProps>) => {
  return items.map((item) => {
    return <item {...item} />
  })
}

const Item = (item: ItemProps) => {
  return (
    <Container>
      <p>{item.name}</p>
      <p>{item.phone}</p>
      <Info {..info}>
    <Container/>
  )
}

const Info({no, dap}) => {
  return (
    <Container>
      <p>{item.no}</p>
      <p>{item.no}</p>
    <Container/>
  )
}

list 로 캠슐화 되면 따로 무언가 노출하지 않아도 목록 빵빵 잘 보여줄 수 있다. 이 얼마나 편한가??

하지만 지금 나의 주어진 상황은 이렇지 않았다.

interface ItemProps { 
  name: string;
  phone: string;
}

interface ItemsProps {
  items: Array<ItemProps>;
  onClick?: (data) => void;
}

const List ({items, onClick}: ItemsProps) => {
  const handler = (data) => {
    onClick?.(data)
  }
  
  return items.map((item) => {
    return <item {...item} onClick={handler} />
  })
}

const Item = (item: Item, onClick) => {
  const handler = () => {
    onClick?.({...item, myLogIs: `noDap-${item.name}`})
  }
  return (
    <Container onClick={handler}>
      <p>{item.name}</p>
      <p>{item.phone}</p>
    <Container/>
  )
}

뭐 이런식의 행동 주입이었다.
게다가 이 행동은 거진 로그를 보낸다던가 등등 딱 고정된 무언가이다.

const MyComponent = () => {
  const logger = useLogger();
  const items = useGetItems(); 
  const onClick = (data) => {
    logger(data);
  }

  return <List item={items} onClick={onclick} />
}

이런식인데, 이게 값만 내리기도 벅찬 이 상황에서 동작까지 내리니 중간에 레이어만 끼어도 난리가 난다.
재사용성을 극대화 하기위해서 행동 또한 내려준다는데…

그래서 나는 HTML 을 좀 더 보자고 했다.

  • Button Element
  • A Element

두 엘레먼트는 click 에 반응을 한다.
하지만 둘 다 onclick 을 내려 주지 않는다.
동작이 딱 정해진 A Element 는 href 를 활용하여 click 시 href 로 이동한다.
동작이 딱 정해져 있으니 동작을 내려보내기 보다는 변화하는 부분, 곧 어디로 갈지만 내려주면 더 잘 재활용할 수 있게 된다.

interface ItemProps { 
  name: string;
  phone: string;
}


const List ({items}: Array<ItemProps>) => {
  return items.map((item) => {
    return <item {...item} />
  })
}

const Item = (item: Item) => {
  const logger = useLogger();
  const handler = () => {
    logger({...item, myLogIs: `noDap-${item.name}`})
  }
  return (
    <Container onClick={handler}>
      <p>{item.name}</p>
      <p>{item.phone}</p>
    <Container/>
  )
}
const MyComponent = () => {
  const items = useGetItems(); 
  return <List {...items}} />
}

로거가 잘 정리 된 것 같다.
그런데 반복적인 주입이지만 로거의 카테고리가 다르기 때문에 props으로 받아야합니다 라고 하더라.
카테고리 같은 것들은 부모가 아니까 뭐 그렇다는 건데… 그렇다고 onClick 이 갈 필요가 없다.
다시 button 과 a 로 돌아가서 생각해보자.
정적으로 보낼 데이터를 결정할 것이니…

const MyComponent = () => {
  const items = useGetItems(); 
  return <List {...items} data-category='noDap'  />
}

하면 대강 잘 될 것이다.

data-category 를 대대손손 내려줄 것이고, 그 받은 자손이 로그할 때 보내면 된다.

다시 사용할 수 있는 컴포넌트를 만들자

그냥 획 옮겨도 될 컴포넌트를 만들면 된다. 뭔가 주입하지 말자.
근데 그렇게 막 계속 다시 쓸 컴포넌트 인지 생각해보자.
인터페이스를 잘 만들어 주고 코드상 납득 할 수 있게만 하자.