여기서는 render prop을 받는 것으로 headless가 구현되었는데, HOC로 구현될 수도 있다. 혹은 View와 Controller, ViewModel과 View의 패턴으로 구현될 수도 있다. 여러 방법이 있겠지만 여기서 중요한 점은 동전을 뒤집는 매커니즘과 그 매커니즘의 인터페이스를 분리했다는 것이다.
react-table
모든 React Table에서는 useTable hook과 table instance 객체가 리턴된다. 이 table instance 객체는 table을 만들고, table의 state와 상호작용할 수 있는 모든 것을 포함한다.
getting your data
테이블 구조를 생각해보면 보통 rows(행)과 columns(열)로 구성된 구조를 떠올린다. 그렇지만 테이블 구성이 단순히 행과 열의 조합으로 생각하기에는 중첩된 columns(열)과 행 등의 구조를 가질 수 있는 등 점점 복잡한 구조를 가지기 때문에 아래와 같은 구조로 기본 데이터 구조를 정의한다.
여기서 중요한 점은 useMemo를 사용했다는 것이다. 이는 데이터가 매번 렌더될 때마다 새롭게 생성되지 않음을 보장하는 것이다. 만약 useMemo를 쓰지 않는다면 table은 렌더될 때마다 새로운 데이터를 받았다고 생각하기 때문에 매번 많은 로직은 새로 계산하려고 시도하게 된다.
Define Columns
useTable hook에 전달하기 위해 column에 대한 정의를 한다. 역시 마찬가지로 useMemo를 사용했기 때문에 매번 렌더될 때마다 새롭게 계산하지 않고, value를 기억해뒀다가 메모제이션된 value와 실제 value에 차이가 있을 때만 변화시킨다.
1 2 3 4 5 6 7 8 9 10 11 12 13
const columns = React.useMemo( () => [ { Header: 'Column 1', accessor: 'col1', // accessor is the "key" in the data }, { Header: 'Column 2', accessor: 'col2', }, ], [] );
Using the useTable hook
위에서 작성한 data와 column에 대한 정의를 가지고 useTable hook에 전달하여 새로운 table instance를 생성할 수 있다. 즉 useTable은 최소 메모제이션된 columns와 data를 포함한 객체를 제공받아야 한다.
1
const tableInstance = useTable({ columns, data });
Building a basic table UI
table instance는 만들었지만 아직 테이블 마크업과 스타일은 하지 않은 상태이므로 기본적인 테이블 구조를 작성해준다.
React Table은 리액트 훅은 내외부에서 사용하여 구성하고, lifecycle를 관리한다. 그리고 기본적으로 custom react hook과 호환되는 hook을 가진다.
useTable은 가장 기본적으로 사용되는 훅인데, 모든 옵션과 플러그인 훅의 스타팅 포인트로 제공된다. 옵션이 useTable로 전달되면 제공받은 순서대로 모든 플러그인 훅으로 전달되고, 최종 instance를 만들어 결과적으로 table state와 상호작용하는 나만의 table UI를 만들 수 있다.