質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Material-UI

Material-UIは、Material Designを利用可能なオープンソースのReact向けUIコンポーネントキットです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1868閲覧

[React] 2次元配列を含めたテーブルのページネーションについて

shimokitan

総合スコア7

Material-UI

Material-UIは、Material Designを利用可能なオープンソースのReact向けUIコンポーネントキットです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2021/06/05 13:24

編集2021/06/05 14:00

開発環境

  • react v17.0.2

実装内容

2次元配列のデータに応じて、行が追加されるテーブルを実装しています。
(今回の場合、filesの配列が2以上のデータを持っている場合、行が増えている)
テーブルのイメージ画像です

// App.js import { useEffect, useState } from "react"; import MuiPagination from "@material-ui/lab/Pagination"; import { withStyles } from "@material-ui/core/styles"; import Table from "@material-ui/core/Table"; import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; import TableContainer from "@material-ui/core/TableContainer"; import TableHead from "@material-ui/core/TableHead"; import TableRow from "@material-ui/core/TableRow"; import { Rows } from "./Rows"; const initialUsers = [...Array(10).keys()].map((idx) => { if (idx === 3 || idx === 5 || idx === 9) { return { id: idx, name: `user${idx + 1}`, fileCount: 3, files: [ { file: "sample1.csv" }, { file: "sample2.csv" }, { file: "sample3.csv" } ] }; } return { id: idx, name: `user${idx + 1}`, fileCount: 1, files: [ { file: "sample1.csv" } ] }; }); export default function App() { const [rows] = useState(initialUsers); const [page, setPage] = useState(1); const [viewCount, setViewCount] = useState(5); const [count, setCount] = useState(1); useEffect(() => { setCount(Math.ceil(rows.length / viewCount)); }, [rows, viewCount]); const Pagination = withStyles({ root: { display: "inline-block" } })(MuiPagination); return ( <> <TableContainer> <Table> <TableHead> <TableRow> <TableCell>名前</TableCell> <TableCell>ファイル数</TableCell> <TableCell>ファイル</TableCell> </TableRow> </TableHead> <TableBody> {rows.map((row, idx) => { if (page === 1) { if (idx + 1 > viewCount * page) return false; } else { if (idx < viewCount * (page - 1)) return false; if (idx >= viewCount * page) return false; } if (row.files.length === 1) { return ( <TableRow key={row.id}> <TableCell>{row.name}</TableCell> <TableCell>{row.fileCount}</TableCell> <TableCell>{row.files[0].file}</TableCell> </TableRow> ); } return <Rows row={row} idx={idx} />; })} </TableBody> </Table> </TableContainer> <div style={{ textAlign: "center" }}> <div>表示件数: {viewCount}</div> <Pagination count={count} //総ページ数 color="primary" onChange={(e, page) => setPage(page)} page={page} //現在のページ番号 /> </div> </> ); }
// Rows.js import TableCell from "@material-ui/core/TableCell"; import TableRow from "@material-ui/core/TableRow"; export const Rows = (props) => { const { row, idx } = props; return ( <> <TableRow key={idx}> <TableCell>{row.name}</TableCell> <TableCell>{row.fileCount}</TableCell> <TableCell>{row.file}</TableCell> </TableRow> {row.files.map((x, idx) => ( <TableRow key={idx}> <TableCell /> <TableCell /> <TableCell>{x.file}</TableCell> </TableRow> ))} </> ); };

実現したいこと

現状のソースコードですと、下記のイメージ画像の赤枠の行をページネーションの表示件数となっています。
テーブル(赤枠付き)
これをfileが存在する行(イメージ画像では7件)を表示件数としてページネーションを実装したいのですが、実装のイメージができず。。

実装自体を見直すべきでしょうか?もしくは今の実装に付け加えで実現できますでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんな感じでしょうか。

js

1const initialUsers = [...Array(10).keys()].map(idx => { 2 const fileCount = Math.floor(Math.random() * 5) + 1; 3 return { 4 id: idx, 5 name: `user${idx + 1}`, 6 fileCount, 7 files: [...Array(fileCount).keys()].map(i => ({ file: `sample${i + 1}.csv` })) 8 }; 9}); 10 11function makeRows(users) { 12 return users.flatMap(row => row.files.map((_, idx) => ({ row, idx }))); 13} 14 15export default function App() { 16 const rows = makeRows(initialUsers); 17 const [page, setPage] = useState(1); 18 19 const viewCount = 7; 20 const count = Math.ceil(rows.length / viewCount); 21 22 const Pagination = withStyles({ 23 root: { 24 display: "inline-block" 25 } 26 })(MuiPagination); 27 28 return ( 29 <> 30 <TableContainer> 31 <Table> 32 <TableHead> 33 <TableRow> 34 <TableCell>名前</TableCell> 35 <TableCell>ファイル数</TableCell> 36 <TableCell>ファイル</TableCell> 37 </TableRow> 38 </TableHead> 39 <TableBody> 40 {[...Array(viewCount).keys()].map(i => { 41 const rowIdx = viewCount * (page - 1) + i; 42 if (rowIdx >= rows.length) { return undefined; } 43 const { row, idx } = rows[rowIdx]; 44 return <Rows key={`${row.id}-${idx}`} row={row} idx={idx} top={i === 0} />; 45 })} 46 </TableBody> 47 </Table> 48 </TableContainer> 49 <div style={{ textAlign: "center" }}> 50 <div>表示件数: {viewCount}</div> 51 <Pagination 52 count={count} //総ページ数 53 color="primary" 54 onChange={(e, page) => setPage(page)} 55 page={page} //現在のページ番号 56 /> 57 </div> 58 </> 59 ); 60}

js

1export const Rows = ({ row, idx, top }) => { 2 if (row.fileCount == 1) { 3 return ( 4 <TableRow> 5 <TableCell>{row.name}</TableCell> 6 <TableCell>{row.fileCount}</TableCell> 7 <TableCell>{row.files[0].file}</TableCell> 8 </TableRow> 9 ); 10 } else if (idx > 0 && !top) { 11 return ( 12 <TableRow> 13 <TableCell /> 14 <TableCell /> 15 <TableCell>{row.files[idx].file}</TableCell> 16 </TableRow> 17 ); 18 } else { 19 return ( 20 <> 21 <TableRow> 22 <TableCell>{row.name}</TableCell> 23 <TableCell>{row.fileCount}</TableCell> 24 <TableCell></TableCell> 25 </TableRow> 26 27 <TableRow> 28 <TableCell /> 29 <TableCell /> 30 <TableCell>{row.files[idx].file}</TableCell> 31 </TableRow> 32 </> 33 ); 34 } 35}

投稿2021/06/05 22:14

編集2021/06/05 22:27
hoshi-takanori

総合スコア7895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問