react 您所在的位置:网站首页 三国志神话版攻略君主传承什么武将好 react

react

#react| 来源: 网络整理| 查看: 265

react-tableについて

ReactでテーブルのUIを作成するのにおいて必要な機能をまとめてくれているライブラリになります。 Headless UIのため、デザインは自身で作成をする形になります。(今回のサンプルではMUIを使用) react-table npmへのリンク

動作環境 @emotion/react: 11.10.6, @emotion/styled: 11.10.6, @mui/icons-material: 5.11.11, @mui/material: 5.11.15, @tanstack/react-table: 8.8.5, react: 18.2.0, 使用した機能 headerのカスタム cellのカスタム フィルタリング ソート ページネーション 使用した機能の説明(header、cellのカスタム)

columnsの設定により対応可能です。項目によってソートの可否を分けたかったため、ソート可能なものとそうでないものでheaderを変更しています。 react-tableではカラムの定義を行うのですが、その時にheaderに表示させたい内容を指定することで対応可能です。(cellも同じ要領です)

// getCustomHeader、getCustomBodyはJSXを返す const COLUMNS: ColumnDef[] = [ { header: (props) => getCustomHeader("発注日", true, props), accessorKey: "orderDate", cell: (props) => getCustomBody(props, "center", false), filterFn: (row, id) => dateAndNumberFilter(row, id) }, 使用した機能の説明(フィルタリング)

これもcolumnsの設定で対応可能です。filterFnでは、行ごとのデータ(row)を受け取ることが可能なので、それを使用して抽出条件を記載します。 ※booleanを返却(trueは表示、falseは非表示)

使用した機能の説明(ソート)

react-tableのoptionにstate.sortingで設定します。 ※{ id: string, desc: boolean }[]の形式

const table = useReactTable({ data: data, columns: COLUMNS, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel(), getPaginationRowModel: getPaginationRowModel(), state: { sorting: sorting, columnFilters: filterConditions, pagination: { pageIndex: pageSetting.pageIndex, pageSize: pageSetting.pageSize } } }); 使用した機能の説明(ページネーション)

react-tableのoptionにstate.paginationで設定します。 ※pageIndexは表示させたいページを設定。pageSizeは1ページ毎の表示件数を設定。

コードサンプル(全量)

今回試してみたコードの全量になります。

import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import { Box, Button, MenuItem, Select, Table, TableBody, TableCell, TableHead, TableRow, TableSortLabel, Typography, TextField } from "@mui/material"; import { common } from "@mui/material/colors"; import { CellContext, ColumnDef, flexRender, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, HeaderContext, Row, SortingState, useReactTable } from "@tanstack/react-table"; import React, { useState } from "react"; const data = [ { orderDate: "2023/04/03", maker: "メーカー1", item: "テスト部品1", price: 1000 }, { orderDate: "2023/04/04", maker: "メーカー2", item: "テスト部品2", price: 1001 }, { orderDate: "2023/04/05", maker: "メーカー3", item: "テスト部品3", price: 1002 }, { orderDate: "2023/04/06", maker: "メーカー4", item: "テスト部品4", price: 1003 } ]; export const App = () => { const [filterConditions, setFilterConditions] = useState< { id: string; value: string | number }[] >([]); const [sorting, setSorting] = React.useState([ { id: "orderDate", desc: true } ]); const [pageSetting, setPageSetting] = useState({ pageIndex: 0, pageSize: 2 }); const getCustomHeader = ( name: string, isSortable: boolean, props: HeaderContext ) => isSortable ? ( { if (props.header.id === sorting[0].id) { setSorting([{ ...sorting[0], desc: !sorting[0].desc }]); } else { setSorting([{ id: props.header.id, desc: true }]); } }} IconComponent={() => ( )} > {name} ) : ( {name} ); const getCustomBody = ( props: CellContext, align: "center" | "right" | "left", isCurrency: boolean ) => isCurrency ? ( {props.cell.getValue().toLocaleString("ja-JP", { style: "currency", currency: "JPY" })} ) : ( {props.cell.getValue()} ); const dateAndNumberFilter = (row: Row, id: string) => { const condition = filterConditions.find( (condition) => condition.id === id && condition.value ); if (!condition || condition.value === null) { return true; } let dataVal: number; let conditionVal: number; if (typeof condition.value === "string") { try { dataVal = new Date(row.getValue(id) as string).getTime(); conditionVal = new Date(condition.value.replace("-", "/")).getTime(); } catch { return true; } } else { dataVal = row.getValue(id) as number; conditionVal = condition.value as number; } if (dataVal === conditionVal) { return true; } else { return false; } }; const stringFilter = (row: Row, id: string) => { const condition = filterConditions.find( (condition) => condition.id === id && condition.value ); if ( !condition || condition.value === null || typeof condition.value !== "string" ) { return true; } if ((row.getValue(id) as string).includes(condition.value)) { return true; } else { return false; } }; const onChangeCondition = (id: string, value: string | number) => { setFilterConditions([ ...filterConditions.filter((condition) => condition.id !== id), { id, value } ]); }; // globalFilterもある // globalFilter特定の検索ワードが存在するかどうかでフィルター const COLUMNS: ColumnDef[] = [ { header: (props) => getCustomHeader("発注日", true, props), accessorKey: "orderDate", cell: (props) => getCustomBody(props, "center", false), filterFn: (row, id) => dateAndNumberFilter(row, id) }, { header: (props) => getCustomHeader("メーカー", false, props), accessorKey: "maker", cell: (props) => getCustomBody(props, "left", false), filterFn: (row, id) => stringFilter(row, id) }, { header: (props) => getCustomHeader("部品名", false, props), accessorKey: "item", cell: (props) => getCustomBody(props, "left", false), filterFn: (row, id) => stringFilter(row, id) }, { header: (props) => getCustomHeader("金額", true, props), accessorKey: "price", cell: (props) => getCustomBody(props, "right", true), filterFn: (row, id) => dateAndNumberFilter(row, id) } ]; const table = useReactTable({ data: data, columns: COLUMNS, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel(), getPaginationRowModel: getPaginationRowModel(), state: { sorting: sorting, columnFilters: filterConditions, pagination: { pageIndex: pageSetting.pageIndex, pageSize: pageSetting.pageSize } } }); return ( condition.id === "orderDate") ?.value ?? "" } onChange={(e) => { onChangeCondition("orderDate", e.target.value); }} /> condition.id === "maker") ?.value ?? "" } onChange={(e) => { onChangeCondition("maker", e.target.value); }} /> condition.id === "item") ?.value ?? "" } onChange={(e) => { onChangeCondition("item", e.target.value); }} /> condition.id === "price") ?.value ?? "" } onChange={(e) => { const num = Number(e.target.value); if (isNaN(num)) return; onChangeCondition("price", num); }} /> {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {flexRender( header.column.columnDef.header, header.getContext() )} ))} ))} {table.getRowModel().rows.map((row) => { return ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext() )} ))} ); })} setPageSetting((old) => { return { ...pageSetting, pageIndex: old.pageIndex - 1 }; }) } > 前のページ setPageSetting({ ...pageSetting, pageIndex: e.target.value as number }) } > {[...Array(table.getPageCount())].map((_, index) => ( {table.getPageCount() !== 0 ? `${index + 1}/${table.getPageCount()}` : 0} ))} setPageSetting((old) => { return { ...pageSetting, pageIndex: old.pageIndex + 1 }; }) } > 次のページ ); }; イメージ

入力部分は非常に簡易ですが、動作イメージです。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有