결과부터 빠르게 봅시다
🙄 서로 다른 컬럼을 가진 데이터들은 어떻게 thead를 구성해야 할까
페이지에서 column 배열을 만들어 테이블 컴포넌트에게 전달하고 내부에서 테이블 헤더를 생성한다
🤨 서로 다른 타입을 가진 데이터를 하나의 테이블에서 어떻게 분기처리 해야 할까
😎 문자열순, 날짜순으로 정렬하도록 하려면 어떻게 구현할 수 있을까
배열의 sort함수로 data를 상황에 맞게 재가공한 뒤 반환한다
테이블의 헤더를 구성할 헤더를 먼저 만듭니다
// pages/notice/index.tsx
function Notice() {
const columns = [
{
accessor: 'title',
value: '제목',
sort: true,
},
{
accessor: 'name',
value: '작성자',
},
{
accessor: 'createDate',
value: '작성일',
sort: true,
},
]
return (
<>
<Head>
<title>공지사항</title>
</Head>
<SortTable columns={columns} />
</>
)
}
export default Notice
accessor: 컬럼의 Key가 됨
value: 컬럼에 표시되는 값
sort: true일 시 해당 컬럼 열의 데이터를 재정렬함
columns 정보가 담긴 데이터를 SortTable 컴포넌트로 전달한다
다음은 공지사항 목록을 생성하기 위한 데이터를 만들어 준다
export noticeData = [
{
id: 3
title: '테스트 글입니다3'
createDate: '2023-04-10T14:13:52'
},
{
id: 2
title: '테스트 글입니다2'
createDate: '2023-04-09T14:13:52'
},
{
id: 1
title: '테스트 글입니다'
createDate: '2023-04-08T14:13:52'
},
]
이제 생성한 데이터와 컬럼 정보를 받을 컴포넌트를 만들어 보죠
// components/SortTable/index.tsx
import React, { useState, useMemo } from 'react'
interface SortTableProps<T> {
columns: ColumnsProps[]
data?: T[]
renderItem: (item: T) => React.ReactNode
}
interface ColumnsProps {
accessor: string
value: string
sort?: boolean
}
function SortTable<T extends unknown>({
columns,
data = [],
renderItem,
}: SortTableProps<T>): JSX.Element {
const [order, setOrder] = useState('')
const [toggle, setToggle] = useState(true)
const makeSortData = () => {} // 여기서 데이터를 재정렬함
// [3]
const sortedData = useMemo(() => makeSortData(), [toggle])
// [2]
const handleDataToggle = (accessor: string) => {
setOrder(accessor)
setToggle(!toggle)
}
// [1]
const headerGroup = columns.map(column =>
column.sort ? (
<TableHeadCell key={`table-head-${column.value}`}>
{column.value}
<p onClick={() => handleDataToggle(column.accessor)}>리스트 재정렬</p>
</TableHeadCell>
) : (
<TableHeadCell key={`table-head-${column.value}`}>{column.value}</TableHeadCell>
),
)
return (
<TableWrapper>
<Table>
<TableHead>
<tr>{headerGroup}</tr>
</TableHead>
<TableBody>
{sortedData?.map((item, index) => (
<tr key={`table-row-${index}`}>{renderItem(item)}</tr>
))}
</TableBody>
</Table>
</TableWrapper>
)
}
export default SortTable
마지막으로 원하는 조건에 맞춰 리스트를 재정렬 해본다
const makeSortData = () => {
switch (order) {
case 'title':
return data.sort((a, b) => (a > b ? 1 : -1))
case 'createDate':
return data.sort((a, b) =>
!toggle
? new Date(a[order]).getTime() - new Date(b[order]).getTime()
: new Date(b[order]).getTime() - new Date(a[order]).getTime(),
)
default:
return data
}
}
위의 코드에서는 컬럼의 키에 따라 문자열과 날짜순으로 정렬하였지만
case를 추가하여 가나다순 혹은 특정 값에 따라 정렬 할 수도 있다.