Käyttötarkoitus
UseSort
-hookilla voi järjestää objekteja sisältävän listan tietyn avaimen ja arvon perusteella.
Sillä voi järjestää tekstiä, numeroita ja välimerkkejä sisältäviä merkkijonoja ja tarvittaessa järjestyksen voi kieliversioida.
Järjestettävän arvon tulee olla teksti- tai numeromuotoinen. Esimerkiksi päivämäärät tulee antaa ISO-muodossa (2024-12-01) ja
formatoida näytettäessä haluttuun muotoon. Muu data, jonka perusteella ei järjestetä, voi olla mitä tahansa, eikä se vaikuta järjestyksen toimintaan.
Esimerkki taulukon järjestämisestä
function SortableTable() {
const headers = [
{
name: "Etuudet",
key: "name",
align: "textual",
type: "string",
},
{
name: "2023 milj. €",
key: "year2023",
align: "numeric",
type: "number",
},
{
name: "2022 milj. €",
key: "year2022",
align: "numeric",
type: "number",
},
];
const rows = [
{
id: 1,
name: "Eläke-etuudet",
year2023: 2576.2,
year2022: 2476.6,
},
{
id: 2,
name: "Vammaistuet",
year2023: 622.0,
year2022: 573.9,
},
{
id: 3,
name: "Sairausvakuutusetuudet",
year2023: 4804.9,
year2022: 5032.6,
},
{
id: 4,
name: "Kuntoutus",
year2023: 785.4,
year2022: 713.2,
},
{
id: 5,
name: "Työttömyysetuudet",
year2023: 1933.5,
year2022: 1844.5,
},
{
id: 6,
name: "Lapsiperheiden etuudet",
year2023: 1819.0,
year2022: 1914.6,
},
];
const { data, sortKey, sortOrder, requestSort } = useSort(rows, {
locale: "fi",
});
const orderLabels = {
none: "ei järjestystä",
ascending: "järjestetty nousevasti",
descending: "järjestetty laskevasti",
};
const orderKeyLabel = headers.find((el) => el.key === sortKey)?.name;
const orderLabel = orderLabels[sortOrder];
return (
<>
<div>
<p>
<strong>sortKey</strong>: {sortKey}
</p>
<p>
<strong>sortOrder</strong>: {sortOrder}
</p>
</div>
<Table orderKeyLabel={orderKeyLabel} orderLabel={orderLabel}>
<TableHead>
<TableHeadRow>
{headers.map(({ key, name, align }) => (
<TableHeader
scope="col"
key={key}
align={align}
onClick={() => requestSort(key)}
order={sortKey === key ? sortOrder : null}
>
{name}
</TableHeader>
))}
</TableHeadRow>
</TableHead>
<TableBody>
{data.map((row) => (
<TableRow key={row.id}>
{headers.map(({ key, align, type }) => (
<TableCell key={`${key}-${row.id}`} align={align}>
{type === "number" && new Intl.NumberFormat("fi").format(row[key])}
{type !== "number" && row[key]}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</>
);
}
Oletusjärjestyksen asettaminen
UseSort
-hookille voidaan välittää defaultOrder
-parametri, joka asettaa oletusjärjestyksen. Myös useSort
-hookin palauttamaa setSort
-funktiota voi hyödyntää tarvittaessa järjestyksen asettamiseen.
function SortableTable() {
const headers = [
{
name: "Etuudet",
key: "name",
align: "textual",
type: "string",
},
{
name: "2023 milj. €",
key: "year2023",
align: "numeric",
type: "number",
},
{
name: "2022 milj. €",
key: "year2022",
align: "numeric",
type: "number",
},
];
const rows = [
{
id: 1,
name: "Eläke-etuudet",
year2023: 2576.2,
year2022: 2476.6,
},
{
id: 2,
name: "Vammaistuet",
year2023: 622.0,
year2022: 573.9,
},
{
id: 3,
name: "Sairausvakuutusetuudet",
year2023: 4804.9,
year2022: 5032.6,
},
{
id: 4,
name: "Kuntoutus",
year2023: 785.4,
year2022: 713.2,
},
{
id: 5,
name: "Työttömyysetuudet",
year2023: 1933.5,
year2022: 1844.5,
},
{
id: 6,
name: "Lapsiperheiden etuudet",
year2023: 1819.0,
year2022: 1914.6,
},
];
const defaultOrder = { key: "name", order: "ascending" };
const { data, sortKey, sortOrder, requestSort, setSort } = useSort(rows, {
locale: "fi",
defaultOrder,
});
const orderLabels = {
none: "ei järjestystä",
ascending: "järjestetty nousevasti",
descending: "järjestetty laskevasti",
};
const orderKeyLabel = headers.find((el) => el.key === sortKey)?.name;
const orderLabel = orderLabels[sortOrder];
return (
<>
<div>
<p>
<strong>sortKey</strong>: {sortKey}
</p>
<p>
<strong>sortOrder</strong>: {sortOrder}
</p>
<p>
<Button onClick={() => setSort(defaultOrder.key, defaultOrder.order)} variant="primary" appearance="outline">
Palauta oletus
</Button>
</p>
</div>
<Table orderKeyLabel={orderKeyLabel} orderLabel={orderLabel}>
<TableHead>
<TableHeadRow>
{headers.map(({ key, name, align }) => (
<TableHeader
scope="col"
key={key}
align={align}
onClick={() => requestSort(key)}
order={sortKey === key ? sortOrder : null}
>
{name}
</TableHeader>
))}
</TableHeadRow>
</TableHead>
<TableBody>
{data.map((row) => (
<TableRow key={row.id}>
{headers.map(({ key, align, type }) => (
<TableCell key={`${key}-${row.id}`} align={align}>
{type === "number" && new Intl.NumberFormat("fi").format(row[key])}
{type !== "number" && row[key]}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</>
);
}
Esimerkki räätälöidyn järjestämisen toteuttamisesta
useSort
-hookin palauttamille requestSort
tai setSort
-funktioille voidaan välittää parametrina sortFunction
- tai valueFunction
-funktiot räätälöidyn järjestämisen toteuttamiseen.
function SortableTable() {
const headers = [
{
name: "Etuudet",
key: "name",
align: "textual",
type: "string",
},
{
name: "2023 milj. €",
key: "year2023",
align: "numeric",
type: "number",
},
{
name: "2022 milj. €",
key: "year2022",
align: "numeric",
type: "number",
},
{
name: "Muutos %",
key: "change",
align: "numeric",
type: "number",
},
];
const rows = [
{
id: 1,
name: "Eläke-etuudet",
year2023: 2576.2,
year2022: 2476.6,
},
{
id: 2,
name: "Vammaistuet",
year2023: 622.0,
year2022: 573.9,
},
{
id: 3,
name: "Sairausvakuutusetuudet",
year2023: 4804.9,
year2022: 5032.6,
},
{
id: 4,
name: "Kuntoutus",
year2023: 785.4,
year2022: 713.2,
},
{
id: 5,
name: "Työttömyysetuudet",
year2023: 1933.5,
year2022: 1844.5,
},
{
id: 6,
name: "Lapsiperheiden etuudet",
year2023: 1819.0,
year2022: 1914.6,
},
];
const calculatePercentage = ({ year2023, year2022 }) =>
parseFloat((((year2023 - year2022) / year2022) * 100.0).toFixed(1));
const sortByNumeric = (a, b) => a - b;
const { data, sortKey, sortOrder, requestSort } = useSort(rows, { locale: "fi" });
const orderLabels = {
none: "Ei järjestystä",
ascending: "Nouseva järjestys",
descending: "Laskeva järjestys",
};
const orderKeyLabel = headers.find((el) => el.key === sortKey)?.name;
const orderLabel = orderLabels[sortOrder];
return (
<Table orderKeyLabel={orderKeyLabel} orderLabel={orderLabel}>
<TableHead>
<TableHeadRow>
{headers.map(({ key, name, align }) => (
<TableHeader
scope="col"
key={key}
align={align}
onClick={key === "change" ? () => requestSort(null, sortByNumeric, calculatePercentage) : undefined}
order={key === "change" ? sortOrder : null}
>
{name}
</TableHeader>
))}
</TableHeadRow>
</TableHead>
<TableBody>
{data.map((row) => (
<TableRow key={row.id}>
{headers.map(({ key, align, type }) => (
<TableCell key={`${key}-${row.id}`} align={align}>
{key !== "change" && type === "number" && new Intl.NumberFormat("fi").format(row[key])}
{key !== "change" && type !== "number" && row[key]}
{key === "change" && new Intl.NumberFormat("fi").format(calculatePercentage(row))}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
);
}