使用 React Table 逐行显示对象数组?
Display an array of objects row-by-row using React Table?
我想在不更改 data
模型的情况下逐行显示电影。
这是我的代码:
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>
);
}
目前看起来像:
这是直接 link 到它:https://codesandbox.io/s/modest-sanderson-z0keq?file=/src/App.tsx
我的电影列表是一个对象数组,那么如何将它显示在演员姓名旁边?所以它看起来像:
没有其他方法可以做到这一点,只能像库的作者提到的那样将数据展平,所以我是这样做的:
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>
);
}
我想在不更改 data
模型的情况下逐行显示电影。
这是我的代码:
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>
);
}
目前看起来像:
这是直接 link 到它:https://codesandbox.io/s/modest-sanderson-z0keq?file=/src/App.tsx
我的电影列表是一个对象数组,那么如何将它显示在演员姓名旁边?所以它看起来像:
没有其他方法可以做到这一点,只能像库的作者提到的那样将数据展平,所以我是这样做的:
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>
);
}