英文:
Rendering and Grouping using React Tables
问题
以下是您要翻译的部分:
I am creating a dynamic table using react based on objects.
The problem is that I am trying to render a new row for every three TD, but instead it is rendering all TDs in the same table row (tr).
How can I separate the TDs into a new TR after a group of 3 TDs have been filled?
Here is my code:
Component rendering table:
export class Roster extends React.Component{
render(){
return(
<div id="tab">
<table >
<tbody>
<tr>
<td colSpan={3}>
<h4>Goalkeepers</h4>
</td>
</tr>
</tbody>
<Goalies/>
</table>
</div>
)
}
}
Component looping through object:
class Goalies extends React.Component{
getTable() {
let td_array = [];
let goal_object = {};
Object.keys(goalies).forEach(function(key) {
goal_object = (goalies[key]);
});
for(const checker in goal_object){
td_array.push(<td key={checker}>{goal_object[checker].p_name} <br/> {goal_object[checker].city} <br/> {goal_object[checker].number}</td>);
}
return(
<tr>
{td_array}
</tr>
)
}
render() {
return (<tbody>{this.getTable()}</tbody>)
}
}
Objects:
export const def = {
1:{
p_name:"p1",
number: 2,
city: "city1"
},
2:{
p_name:"p2",
number: 5,
city: "city2"
},
3:{
p_name:"p3",
number: 3,
city: "city3"
},
4:{
p_name:"p4",
number: 7,
city: "city4"
},
5:{
p_name:"p5",
number: 15,
city: "city5"
},
6:{
p_name:"p6",
number: 21,
city: "city6"
}
}
I want to get:
td1 | td2 | td3 |
---|---|---|
td4 | td5 | td6 |
instead, I am getting:
| td1 | td2 | td3 | td4 | td5 | td6 |
|:---- |:------:| -----:|
英文:
I am creating a dynamic table using react based on objects.
The problem is that I am trying to render a new row for every three TD, but instead it is rendering all TDs in the same table row (tr).
How can I separate the TDs into az new TR after a group of 3 TDs have been filled?
Here is my code:
Component rendering table:
`export class Roster extends React.Component{
render(){
return(
<div id="tab">
<table >
<tbody>
<tr>
<td colSpan={3}>
<h4>Goalkeepers</h4>
</td>
</tr>
</tbody>
<Goalies/>
</div>
)
}
}`
Component looping through object:
`class Goalies extends React.Component{
getTable() {
let td_array = [];
let goal_object = {};
Object.keys(goalies).forEach(function(key) {
goal_object = (goalies[key]);
});
for(const checker in goal_object){
td_array.push(<td key={checker}>{goal_object[checker].p_name} <br/> {goal_object[checker].city} <br/> {goal_object[checker].number}</td>);
}
return(
<tr>
{td_array}
</tr>
)
}
render() {
return (<tbody>{this.getTable()}</tbody>)
}
}`
Objects:
export const def = {
1:{
p_name:"p1",
number: 2,
city: "city1"
},
2:{
p_name:"p2",
number: 5,
city: "city2"
},
3:{
p_name:"p3",
number: 3,
city: "city3"
},
4:{
p_name:"p4",
number: 7,
city: "city4"
},
5:{
p_name:"p5",
number: 15,
city: "city5"
},
6:{
p_name:"p6",
number: 21,
city: "city6"
}
}
I want to get:
td1 | td2 | td3 |
---|---|---|
td4 | td5 | td6 |
instead, I am getting:
| td1 | td2 | td3 | td4 | td5 | td6 |
|:---- |:------:| -----:|
I tried using conditional statements, pushing into a new array...
答案1
得分: 0
为了实现您想要的布局,正确的HTML标记如下所示:
<table>
<thead>
<tr>
<th colspan="3">
<h4>守门员</h4>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
</tr>
<tr>
<td>td4</td>
<td>td5</td>
<td>td6</td>
</tr>
</tbody>
</table>
首先,您需要将项目分组为大小为 n
(在您的情况下为3)的数组。您可以使用生成器函数:
function* toChunks(arr, n) {
for (let i = 0; i < arr.length; i += n) {
yield arr.slice(i, i + n);
}
}
const rows = [...toChunks(items, 3)];
作为另一种选择,您也可以使用:
const chunk = (arr, n) =>
[...Array.from({ length: Math.ceil(arr.length / n) }).keys()].map((key) =>
arr.slice(key * n, (key + 1) * n)
);
const rows = chunk(items, 3);
有了上述行,您的组件将如下所示:
const Goalies = ({ rows }) => (
<tbody>
{rows.map((row, rk) => (
<tr key={rk}>
{row.map((cell, ck) => (
<td key={ck}>{cell.number}</td>
))}
</tr>
))}
</tbody>
);
然而,根据您的数据,我认为您根本不应该在这里使用 table
。您想要的布局可以更容易地通过以下方式实现:
const Cells = ({ items }) => (
<div className="myWrapper">
{items.map((item, key) => (
<div key={key}>{item.number}</div>
))}
</div>
)
以及以下CSS模型之一:
.myWrapper {
display: flex;
flex-wrap: wrap;
}
.myWrapper > * {
width: calc(100%/3)
}
/* 或者替代方式: */
.myWrapper {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr))
}
英文:
In order to achieve the layout you're after, the correct HTML markup would look like this:
<table>
<thead>
<tr>
<th colspan="3">
<h4>Goalkeepers</h4>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
</tr>
<tr>
<td>td4</td>
<td>td5</td>
<td>td6</td>
</tr>
</tbody>
</table>
First, you'll want to group your items into arrays of n
(3 in your case). I'd use a generator function:
function* toChunks(arr, n) {
for (let i = 0; i < arr.length; i += n) {
yield arr.slice(i, i + n)
}
}
const rows = [...toChunks(items, 3)]
As an alternative, you could also use:
const chunk = (arr, n) =>
[...Array.from({ length: Math.ceil(arr.length / n) }).keys()].map((key) =>
arr.slice(key * n, (key + 1) * n)
)
const rows = chunk(items, 3)
Given the above rows, your component would look like this:
const Goalies = ({ rows }) => (
<tbody>
{rows.map((row, rk) => (
<tr key={rk}>
{row.map((cell, ck) => (
<td key={ck}>{cell.number}</td>
))}
</tr>
))}
</tbody>
)
However, by looking at your data I think you shouldn't be using a <table>
here at all. The layout you're after could easier be achieved with:
const Cells = ({ items }) => (
<div className="myWrapper">
{items.map((item, key) => (
<div key={key}>{item.number}</div>
))}
</div>
)
along with any of the following CSS models:
.myWrapper {
display: flex;
flex-wrap: wrap;
}
.myWrapper > * {
width: calc(100%/3)
}
/* or alternatively: */
.myWrapper {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论