# 2021년 4월, Monthly I Learned

# 4/10

# UI 컴포넌트별로 신경써야할 것

https://uiplaybook.dev/

  1. 툴팁
    1. Focus되었을때도 보여야하고, Esc누르거나 다른곳 네비게이팅하면 사라진다.
      1. 툴팁 자체는 포커스되면 안됨.
    2. 기본 위치를 지정할 수 있게 해주되 공간이 없으면 다른 곳에 보이도록.
    3. 필수적인 정보를 넣지 말것
    4. 간결한 텍스트
    5. 툴팁 안에 인터렉티브한 요소(버튼, 링크 등)을 넣지 말것. 이걸 원하면 Popover를 쓸것.
    6. 개발팁
      1. 툴팁 넘 빨리 보여주면 UX에 안좋음. 100ms하삼.
      2. 부모가 짤라버릴수도 있으니 DOM hierarchy에서 부모 밖에 위치시킨다.
      3. disabled된 element(e.g. <button>)은 마우스이벤트 안먹으니까 Pointer events를 대신 써라. 아니면 위에 <span>등으로 감싸던가.
    7. 접근성
    8. exc누르면 사라짐.
    9. 툴팁 컨테이너 element에 role="tooltip"
    10. 툴팁 대상 되는 element에 aria-describedby="툴팁엘리먼트id"로 엮어줘라
      1. aria-describedby는 툴팁뿐 아니라 보충정보를 전달해줘야하는 곳에 다 사용가능. (e.g. input에 힌트 '비밀번호는 10자 이상이어야 합니다')
  2. 버튼
    1. Active와 Focus의 차이: Active는 눌려진 상태, Focus는 포커스.
      1. 포커스 스타일 꼭 넣어줘야한다! 그 전까진 outline: 0 넣지마
    2. 접근성
      1. W3 Success Criterion for Target Size에 따라 44px이상이어야 함.
      2. 텍스트가 없는 아이콘버튼 등은 area-label넣어줘
      3. button태그의 기본 접근성지원이 많아서 무조건 태그 쓰는걸로. div등으로 하지 말구.
  3. 셀렉트
    1. 접근성 1부터 대응하는게 큰일일테니 native <select>엘리먼트 쓰는걸 추천
    2. typeahead로 검색 가능해야한다
    3. 여유공간에 따라 다이나믹하게 보여야 한다
    4. onclick대신 mousedown이벤트를 쓰면 사용자가 한번에 셀렉하게 할 수 있다(onclick은 마우스를 떼야 발발됨)
    5. 셀렉트 열면 드롭다운으로 포커스 가야함 (Focus trap)
  4. 노티피케이션 (스낵바/토스트... 근데 좀더 행동을 self describe하기 위해선 노티피케이션이란 이름이 좋겠다~)
    1. 액션에 대한 피드백 보여줄 때 씀(네트워크 에러, 저장되었습니다). 좀 더 끼어들면서 추가액션을 유도하는 노티피케이션은 AlertDialog를 대신 써라.
    2. 보통 4초 뒤에 사라짐. 액셔너블한 노티피케이션(e.g. 지웠습니다 - undo)은 10초도 무방.
    3. hover하면 타이머를 멈춤. 나가면 타이머 restart
    4. 접근성: role 어트리뷰트를 꼭 써야한다.
      1. role="alert" : 스크린리더가 다른거 읽다가도 즉각으로 읽어줌. e.g. 네트워크 에러 보여주는등의 상황
      2. role="status": 다 읽기까지를 기다림 e.g. 저장되었습니다 보여주는 등의 상황
      3. https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_status_role

# 4/15

# Compound패턴과 리액트 훅

https://kentcdodds.com/blog/compound-components-with-react-hooks

  • 특정 목표를 해결하기 위해 붙어다녀야 하는 컴포넌트(e.g. Select / Option)들이 있을때 유연하게 API설계하는 방법
    • React.cloneElement나 React context로 서로간의 관계를 만들어준다.
<Toggle onToggle={(on) => console.log(on)}>
  <Toggle.On>The button is on</Toggle.On>
  <Toggle.Off>The button is off</Toggle.Off>
  <Toggle.Button />
</Toggle>

(kent 블로그에서 코드 복사해옴)

const ToggleContext = React.createContext();

function Toggle(props) {
  const [on, setOn] = React.useState(false);
  const toggle = React.useCallback(() => setOn((oldOn) => !oldOn), []);
  useEffectAfterMount(() => {
    props.onToggle(on);
  }, [on]);
  const value = React.useMemo(() => ({ on, toggle }), [on]);

  // context안에 on, toggle을 전달
  return (
    <ToggleContext.Provider value={value}>
      {props.children}
    </ToggleContext.Provider>
  );
}
function useToggleContext() {
  const context = React.useContext(ToggleContext);
  if (!context) {
    throw new Error(
      `Toggle compound components cannot be rendered outside the Toggle component`
    );
  }
  return context;
}
function On({ children }) {
  const { on } = useToggleContext();
  return on ? children : null;
}
function Off({ children }) {
  const { on } = useToggleContext();
  return on ? null : children;
}
function Button(props) {
  const { on, toggle } = useToggleContext();
  return <Switch on={on} onClick={toggle} {...props} />;
}

// Toggle컴포넌트 안에 On, Off, Button 컴포넌트를 static 프로퍼티로 넣음 (optional)
Toggle.On = On;
Toggle.Off = Off;
Toggle.Button = Button;

# 자바스크립트의 메모리관리

https://developer.mozilla.org/ko/docs/Web/JavaScript/Memory_Management

  1. C와같은 저수준 언어는 메모리관리 위해 malloc() / free()를 사용하는데 js는 객체 생성시 자동으로 메모리 할당하고 쓸모없어졌을때 자동으로 해제함(가비지 컬렉션)