I'm using react-table v7.8.0 to create a table with 4 columns. I'd like the the table to be sorted by columns date
and views
. My problem is that the table is only being sorted by the date
column.
I have some pagination and manual sorting that appears to be working as expected. I think I've followed the documentation and I'm unsure where my mistake is.
The data is configured in the following file before being passed to a table
component:
ViewsPageDayTable.js:
const postDateTemplate = { year: "numeric", month: "short", day: "numeric" }
import Link from "@/components/Link"
import { useMemo } from "react"
import siteMetadata from "@/data/siteMetadata"
import Table from "@/components/homeBrewAnalytics/table"
import LocationCountItem from "@/components/homeBrewAnalytics/locationCountItem"
export default function ViewsPageDayTable({ data }) {
const parsedData = []
for (var i = 0; i < data.length; i++) {
const dataRow = {}
for (var j in data[i]) {
if (j === "date") {
var date = new Date(data[i][j])
dataRow["date"] = date.toLocaleDateString(siteMetadata.locale, postDateTemplate)
} else if (j === "page") {
dataRow["page"] = data[i][j]
} else if (j === "country_count") {
var value = 0
if (data[i][j] == null) {
value = "unknown"
dataRow["country_count"] = null
} else {
value = data[i][j]
value = value.replaceAll("(", "[").replaceAll(")", "]").replaceAll("'", '"')
value = JSON.parse(value)
dataRow["country_count"] = value
}
} else if (j === "views") {
dataRow["views"] = parseInt(data[i][j])
}
}
parsedData.push(dataRow)
}
const PageCellProcessor = ({ value, row: { index }, column: { id } }) => {
return (
<Link href={value} className="hover:underline">
{" "}
{value}{" "}
</Link>
)
}
const LocationCellProcessor = ({ value }) => {
if (value == null) return <div></div>
const result = []
for (var z = 0; z < value.length; z++) {
result.push(<LocationCountItem value={value[z]} />)
}
return (
<div key={value} className="flex flex-shrink">
{result}{" "}
</div>
)
}
const columns = useMemo(
() => [
{
Header: "Date",
accessor: "date",
sortType: (a, b) => {
return new Date(b) - new Date(a)
},
},
{
Header: "Page",
accessor: "page",
Cell: PageCellProcessor,
},
{
Header: "Views",
accessor: "views",
sortType: 'basic',
},
{
Header: "Location",
accessor: "country_count",
Cell: LocationCellProcessor,
},
],
[]
)
return (
<div
id="viewsPerPagePerDay"
className="min-h-32 col-span-3 border-separate border-2 border-slate-800 p-3"
>
<Table columns={columns} data={parsedData} />
</div>
)
}
Table.js:
import { React, useMemo } from "react"
import { useTable, useFilters, useSortBy, usePagination } from "react-table"
import { useState } from "react"
export default function Table({ columns, data, isPaginated = true }) {
const [filterInput, setFilterInput] = useState("")
const handleFilterChange = (e) => {
const value = e.target.value || undefined
setFilter("page", value)
setFilterInput(value)
}
const {
getTableProps,
getTableBodyProps,
headerGroups,
page,
prepareRow,
setFilter,
canPreviousPage,
canNextPage,
pageOptions,
nextPage,
previousPage,
state: { pageIndex, pageSize },
} = useTable(
{
columns,
data,
initialState: {
defaultCanSort: true,
disableSortBy: false,
manualSortBy: true,
sortBy: useMemo(
() => [
{
id: "date",
desc: false,
},
{
id: "views",
desc: true,
},
],
[]
),
pageIndex: 0,
pageSize: 15,
manualPagination: true,
},
},
useFilters,
useSortBy,
usePagination
)
return (
<>
<div className="flex justify-between align-middle">
<div> Page Views</div>
<input
className="mr-0 rounded-sm border border-gray-700 dark:border-gray-500 "
value={filterInput}
onChange={handleFilterChange}
placeholder={" Page name filter"}
/>
</div>
<table {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th
{...column.getHeaderProps(column.getSortByToggleProps())}
className={
column.isSorted ? (column.isSortedDesc ? "sort-desc" : "sort-asc") : ""
}
>
{column.render("Header")}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row, _) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
})}
</tr>
)
})}
</tbody>
</table>
{Boolean(isPaginated) && (
<div id="pagination">
<div id="pageNum">
page {pageIndex + 1} of {pageOptions.length}
</div>{" "}
<div id="nextPrevButtons">
{canPreviousPage ? (
<div id="backButton" onClick={() => previousPage()}>
Previous
</div>
) : null}
{canNextPage ? (
<div id="nextButton" onClick={() => nextPage()}>
Next{" "}
</div>
) : null}
</div>
</div>
)}
</>
)
}