[React] Ag-grid 를 이용한 floating header 제작하기

Front-end/React.js

[React] Ag-grid 를 이용한 floating header 제작하기

조커린 2020. 1. 21. 15:29

css 에서 position:sticky; 하고 top:0;으로 화면 상단에 요소가 붙게 하는 거나

화면에서 절대위치로 버튼등을 넣는 것을 floating button 이나 floating header라고 하더라.

 

완성본은 이런 모양이다

 

이전 앵귤러 테이블을 쓸 때에는 ng data table 자체적으로 위 옆으로 붙는 기능이 있었지만 모바일에서 스크롤 값을 못 읽었고

리액트에서는 전부 하드코딩으로 구현을 하면서 그런 것에 대한 버그는 많이 줄었다.

 

계속 이 테이블 구현을 위한 디벨롭을 하면서 

이전에도 API를 이용하기도 하고, 아예 API를 쓰지 않기도 했었는데 

개발자 분이 UI를 찾고 찾아 발견한 ag-grid가 넘 좋았다. 

 

처음부터 cell의 width값, 테이블의 column수, 높이값, 등을 입력해서 

렌더링 되는 값을 최대한 줄여주는 좋은 API인데

 

여기서 가로 스크롤을 삽입 후 셀을 왼쪽으로 붙게 하는 기능이 있다.

이 기능을 쓰면 마크업확인시 테이블이 왼쪽으로 붙는 것과 오른쪽으로 붙는 쪽으로 나뉘어져 있었음.

보니깐 내부에선 position absolute , 설정된 가로길이값으로 각각 셀들을 왼쪽으로 붙여주고 스크롤 또한 자연스럽게 될 수 있도록 만들어져 있었음.

(하드코딩 할때는 아무래도 상단셀 전체를 화면 기준으로 붙이고, 띄우다보니 그 셀들을 제외한 우측 셀들이 가로스크롤이안먹어 스크롤 좌표값을 감지해 애니메이션으로 다시 스크롤을 줘야했다..쥬륵)

 

ag grid를 쓸 땐 상단 전체 헤더를 상단으로 붙이기만 하면 마크업이 완벽하기 때문에 스크롤 노동을 하지 않아도 되었다.

그래서 .floatthead로 position:fixed top:0;을 넣어 클래스만 토글 시켜 주었다.

 

리액트 특성상 이 페이지에만 이벤트리스너를 넣으면 다른 페이지에서도 리스너가 작동한다.

이문제는 우리 개발자 분이 해결해 주셨다.. ㅠㅠ 코드를 보고 인터넷을 찾아보니 

이 경우에 useeffect 내부의 인자로 빈배열을 넣어서 컴포넌트가 마운트 되고 함수가 한 번만 실행되게 한다.

(이렇지 않으면 state업데이트를 계속 감지해 함수 호출됨 ㅠ 다른데서도 되고..)

   const scrollEventListener = (evt) => {
        var $tbl = document.querySelector(".ag-root") ;
        var $tblHeader = document.querySelector(".ag-header") ;
        var tblTop = $tbl.getBoundingClientRect().top;
        if(tblTop <= -50 ){
            $tblHeader.classList.add("floatthead");
        }else{
            $tblHeader.classList.remove("floatthead");
        }
    }

    React.useEffect(() => {
        if (routerError) {
            Router.push('/')
        } else {
            window.addEventListener('scroll', scrollEventListener)
        }
        return () => {
            fetching = false
            window.removeEventListener('scroll', scrollEventListener)
        }
    }, [])