How to display an array of objects row-by-row? #2252
Answered
by
deadcoder0904
deadcoder0904
asked this question in
General
-
Here's my code: import * as React from "react";
import { useTable } from "react-table";
const borderStyle = {
border: "1px dashed navy"
};
export default function App() {
const data = React.useMemo(
() => [
{
actor: "Johnny Depp",
movies: [
{
name: "Pirates of the Carribean 1"
},
{
name: "Pirates of the Carribean 2"
},
{
name: "Pirates of the Carribean 3"
},
{
name: "Pirates of the Carribean 4"
}
]
}
],
[]
);
const columns = React.useMemo(
() => [
{
Header: "Actor",
accessor: "actor",
},
{
Header: "Movies",
accessor: (row, index) => {
console.log({ row });
// i want to display this row-by-row instead of in 1-row without changing data model
return row.movies.map(movie => movie.name);
}
}
],
[]
);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow
} = useTable({ columns, data });
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()} style={borderStyle}>
{column.render("Header")}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row);
if (i == 0) {
console.log({ row });
}
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell, j) => {
if (i == 0 && j < 2) {
console.log({ cell, i, j });
}
return (
<td
{...cell.getCellProps()}
style={borderStyle}
>
{cell.render("Cell")}
</td>
);
})}
</tr>
);
})}
</tbody>
</table>
);
} It currently looks like: Here's the direct link to it: https://codesandbox.io/s/modest-sanderson-z0keq?file=/src/App.tsx My movie list is an array of objects so how will I display it beside actor name? So it looks like:
|
Beta Was this translation helpful? Give feedback.
Answered by
deadcoder0904
May 11, 2020
Replies: 2 comments
-
@tannerlinsley is there any way to do this without changing the data model? |
Beta Was this translation helpful? Give feedback.
0 replies
-
Tanner answered me on Twitter that I need to flatten the data model. Here's the working solution: import * as React from "react";
import { useTable } from "react-table";
type Data = {
actor: string;
movie: string;
}
const borderStyle = {
border: "1px dashed navy"
};
export default function App() {
const origData = [
{
actor: "Johnny Depp",
movies: [
{
name: "Pirates of the Carribean 1"
},
{
name: "Pirates of the Carribean 2"
},
{
name: "Pirates of the Carribean 3"
},
{
name: "Pirates of the Carribean 4"
}
]
}
];
const newData: Array<Data> = [];
origData.forEach(actorObj => {
actorObj.movies.forEach(movie => {
newData.push({
actor: actorObj.actor,
movie: movie.name
});
});
});
const data = React.useMemo(() => newData, []);
const columns = React.useMemo(
() => [
{
Header: "Actor",
accessor: "actor"
},
{
Header: "Movies",
accessor: "movie"
}
],
[]
);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow
} = useTable({ columns, data });
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()} style={borderStyle}>
{column.render("Header")}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row);
if (i == 0) {
console.log({ row });
}
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell, j) => {
if (i == 0 && j < 2) {
console.log({ cell, i, j });
}
return (
<td
rowSpan={cell.rowSpan}
{...cell.getCellProps()}
style={borderStyle}
>
{cell.render("Cell")}
</td>
);
})}
</tr>
);
})}
</tbody>
</table>
);
} |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
deadcoder0904
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tanner answered me on Twitter that I need to flatten the data model.
Here's the working solution: