useRef로 sliding bar 구현하기

신재민·2021년 1월 14일
0
post-thumbnail

Typescript로 햄버거 메뉴 클릭 시 sliding bar를 구현해보았습니다.

🗂 Structure

 src  
  ├── components
  |      └── common
  |            ├── Header.tsx
  |            ├── Footer.tsx
  |            └─── Slidebar.tsx
  |
  └─── containers
      └── common
           └───HeaderContainer.tsx
  • 전체적인 구조는 생략하고 slidebar 구현에 필요한 파일만 보였습니다.
  1. HeaderContainer.tsx
const HeaderContainer = () => {
  const [open,setOpen] = useState(false);

  const onToggle = () => {
    setOpen(!open);
  }

  return (
    <Container>
      <Header onClick={onToggle}/>
      <Slidebar open={open} onClick={onToggle} />
    </Container>
  )
}
  1. Slidebar.tsx
const Slidebar = ({open,onClick}:ISlide) => {

  const ref = useRef<HTMLUListElement>(null);

  const onMouseDown = (e:any) => {
    if(!ref.current) return ;

    if(!e.path.includes(ref.current)) {
      onClick();
    }
  }

  useEffect(() => {
    if(open) {
      window.addEventListener('mousedown', onMouseDown, true);
    } 

    return () => {
      window.removeEventListener("mousedown", onMouseDown, true);
    }
  },[open]);
  
   return (
    <>
      <UList open={open} ref={ref}>
        <Link to="/"><List>Home</List></Link>
        <Link to="/"><List>????</List></Link>
        <Link to="/"><List>Contact Us</List></Link>
      </UList>
    </>
  )
  1. useRef를 사용하여 UList component를 특정시켜줍니다.
  2. onMouseDown을 통해서 현재 UList가 없을 경우 return시켜 예외처리를 해줍니다.
  3. window 전체에 eventlistner를 걸어주고, 클릭 시에 클릭한 부분의 노드와 루트까지의 노드를 검색하여 ref.current(UList)의 밖의 요소를 클릭했을 시에 onClick을 작동시켜서 slidebar를 닫아주는 방식으로 구현하였습니다.
  4. open을 dependency로 설정하여 open이 false가 될 시에 componentWillUnmount가 발생하여 window에 부착한 event를 지워주는 방식으로 구현하였습니다.
    dependancy(두번째 인자로 넘기는 배열)가 바뀌어서 effect가 달라져야할 때 (이전 effect 청소)
profile
I am jerry

0개의 댓글