
data.sort()
data.sort((a,d)=>{
return a-b
})
5(b) ,1(a) ,4 ,3
const data = ['a', 'b', 'A', 'B']
data.sort((a,b)=>{
return a.lacaleCompare(b)
})
function getSortValue(data){
return data.cost
}
data.sort((a,b)=>{
const valueA = getSortValue(a)
const valusB = getSortValue(b)
if(typeOf valueA ==='string'){
return valueA.localeCompare(valueB)
} else {
return valueA - valueB
}
})
return (valueA - valueB) * -1
Better Solution
const sortOrder = 'asc'
data.sort((a,b)=>{
...
const reverseOrder = sortOrder === 'asc' ? 1 : -1
...
return (valueA - valueB) * reverseOrder
})
Inside 'TablePage'
const config = [
{
label: "Name",
render: (fruit) => fruit.name,
},
{
label: "Color",
render: (fruit) => <div className={`p-3 m-2 ${fruit.color}`}></div>,
},
{
label: "Score",
render: (fruit) => fruit.score,
header: () => <th className="bg-red-500">Score</th>,
},
];
Inside 'Table'
const renderHeaders = config.map((column)=>{
if(column.header){
return column.header()
} else {
return <th key={column.label}>{column.label}</th>;
}
})
THERE IS KEY ISSUES! We are using 'Fragment'
import { Fragment } from "react";
export default function Table({ data, config, keyFn }) {
const renderdHeaders = config.map((column) => {
if (column.header) {
return <Fragment key={column.label}> {column.header()}</Fragment>;
}
return <th key={column.label}>{column.label}</th>;
});
data(array of objects) , config(labe, render)
=> Table Component
We've got a component that will render a table given an array of projects and a list of 'columns'.
We need one function to sort out Data
function getSortValue(fruit){
return fruit.name
}
// sortOrder => 'asc' or 'desc'
Inside Object in Config
sortValue : optional function to describe how to extract values for sorting when this column clicked.
Inside 'TablePage'
data , config({label:'Name', render, sortValue})
=>
Inside 'SortableTable'
=> 'Table'
//Inside 'TablePage'
const config =
[
labe:'Name',
render:()=>{...},
sortValue: (fruit)=>fruit.name
]
//Inside 'SortableTable'
function SortableTable(props){
const {config} = props
const updatedConfig = config.map((column)=>{
if(!column.sortValue){
reutrn column
}
return {...column,
header:()=> <th>{column.label} Is sortable</th>
}
})
return <Table {...props} config={updatedConfig}>
}
//Inside 'SortableTable'
const [sortOrder, setSortOrder] = useState(null)
cons [sortBy , setSortBy] = useState(null)
const handleClick = (label)=>{
if(sortOrder === null){
setSortOrder('asc');
setSortBy(label)
} else if (sortOrder === 'asc'){
setSortOrder('desc');
setSortBy(label)
} else if (sortOrder === 'desc'){
setSortOrder(null);
setSortBy(null)
}
}
...
const updatedConfig = ...
return {
...column,
header:()=>{
<th onClick={()=>hadleClick(column.label)}>{column.label}</th>
}
}
....
//Inside SortableTable
cosnt {config, data} = props
...
// Only sort data when sortOrder&&sortBy are not null
// Make a copy of the 'data' prop
// Find the corrent sortValue function and use it for sorting
let sortedData = data
if(sortOrder && sortBy){
const {sortValue} = config.find((column)=> column.label === sortBy)
sortedData = [...data].sort((a,b)=>{
const valueA = sortValue(a);
const valueB = sortValue(b);
const reverseOrder = sortOrder === 'asc' ? 1:-1;
if(typsOf valueA === 'string'){
return valueA.localeCompare(valueB) * reverseOrder
} else {
return (valueA - valueB) * reverseOrder
}
})
return (
<Table {...props} data={sortedData} config={updatedConfig}>
)
}
//Inside 'SortableTable'
<th onClick={() => handleClick(column.label)}>
{getIcons(column.label, sortBy, sortOrder)}
{column.label}
</th>
//Outside
function getIcons(label, sortBy, sortOrder) {
if (label !== sortBy) {
return (
<div>
<GoArrowSmallUp />
<GoArrowSmallDown />
</div>
);
}
if (sortOrder === null) {
return (
<div>
<GoArrowSmallUp />
<GoArrowSmallDown />
</div>
);
} else if (sortOrder === "asc") {
return (
<div>
<GoArrowSmallUp />
</div>
);
} else if (sortOrder === "desc") {
return (
<div>
<GoArrowSmallDown />
</div>
);
}
}