reactjs - React App - render() - map () - 使用 if-else 条件映射
问题描述
我创建了我的 ReactApp,并希望显示一个包含来自 AWS dynamodb 的数据的表。
我通过 ReactApp 的 render() 中的 map() 成功地将 dynamodb 中的数据通过 json 传输到 ReactApp,我显示的表格如下:
所以现在我需要重新分配表格,如下所示:
所以我计划相应地使用 if-else 语句来渲染表格:但是一旦我在函数中放入 if-else 子句,它就不起作用并且什么都没有显示。所以想向stackoverflow专家寻求建议:)非常感谢
这是我的代码,我卡住的部分在 render() 的返回部分:
class App extends Component {
constructor(props) {
super(props);
this.state = {
hits: [],
isLoading: false,
error: null,
};
}
render() {
const { hits, isLoading, error } = this.state;
if (error) {
return <p>{error.message}</p>;
}
if (isLoading) {
return <p>Loading ...</p>;
}
return (
<form>
<div className="container border border-secondary rounded center">
<div className="row">
<div className="col-12">
{' '}
<h4>
<b>Class Mapping</b>
</h4>{' '}
</div>
</div>
<div className=".col-xs-12 center text-center">
<Table responsive striped bordered hover>
<tr>
<th>Class 1</th>
<th>Class 2</th>
<th>Class 3</th>
<th>Class 4</th>
<th>Class 5</th>
</tr>
<tbody>
{hits.map((hit) => {
if (hit.class === 'Class 1') {
<tr>
<td>{hit.name}}</td> <td></td> <td></td> <td></td> <td></td>{' '}
</tr>;
} else if (hit.class === 'Class 2') {
<tr>
<td></td>
<td>{hit.name}}</td> <td></td> <td></td> <td></td>{' '}
</tr>;
}
})}
</tbody>
</Table>
</div>
</div>
</form>
);
}
async componentDidMount() {
this.setState({ isLoading: true });
const response = await fetch('https://xxxxxxx');
const body = await response.json();
this.setState({ hits: body, isLoading: false, error: null });
}
}
export default App;
解决方案
所以你想要一个看起来像这样的数组:
const hits = [
{ name: 'Tammy', class: 'Class 1' },
{ name: 'Sarah', class: 'Class 2' },
{ name: 'Roland', class: 'Class 3' },
{ name: 'Moshe', class: 'Class 4' },
{ name: 'Peter', class: 'Class 5' },
];
并将其转换为名称数组,按类名排列成列,如下所示:
const rows = [
['Tammy', 'Sarah', 'Roland', 'Moshe', 'Peter'],
['Helen', 'Eric', 'Fiona', 'Darren', 'Andy'],
];
这将需要一些工作。我不认为你将能够在几个地图函数中使用 if/else 语句来完成它。
让我们试试这个。我建议向您的组件添加一个名为 getRows 的类方法。此方法将进行转换。我们首先遍历您hits
的名称并按类对名称进行分组。
然后我们设置一个 while 循环,将名称推送到新的行数组中。虽然我们还有名字,但请继续构建行。每行将根据列选择一个名称并插入它。
最后,当我们都没有名字时,我们可以将行返回给渲染函数。然后我们映射行,并映射每行中的列。我们还需要每个映射元素的唯一键。
获取行()
const getRows = () => {
const columns = ['Class 1', 'Class 2', 'Class 3', 'Class 4', 'Class 5'];
const rows = [];
const groupByColumn = this.state.hits.reduce((acc, next) => {
return { ...acc, [next.class]: [...(acc[next.class] || []), next.name] };
}, {});
const haveNames = () => columns.some((column) => (groupByColumn[column] || []).length > 0);
while (haveNames()) {
const newRow = columns.map((column) => {
return (groupByColumn[column] || []).shift() || '';
});
rows.push(newRow);
}
return rows;
};
完整的组件:
import React, { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
hits: [],
isLoading: false,
error: null,
};
}
async componentDidMount() {
this.setState({ isLoading: true });
const response = await fetch('https://xxxxxxx');
const body = await response.json();
this.setState({ hits: body, isLoading: false, error: null });
}
getRows = () => {
const columns = ['Class 1', 'Class 2', 'Class 3', 'Class 4', 'Class 5'];
const rows = [];
const groupByColumn = this.state.hits.reduce((acc, next) => {
return { ...acc, [next.class]: [...(acc[next.class] || []), next.name] };
}, {});
const haveNames = () => columns.some((column) => (groupByColumn[column] || []).length > 0);
while (haveNames()) {
const newRow = columns.map((column) => {
return (groupByColumn[column] || []).shift() || '';
});
rows.push(newRow);
}
return rows;
};
render() {
if (this.state.error) {
return <p>{error.message}</p>;
}
if (this.state.isLoading) {
return <p>Loading ...</p>;
}
return (
<form>
<div className="container border border-secondary rounded center">
<div className="row">
<div className="col-12">
{' '}
<h4>
<b>Class Mapping</b>
</h4>{' '}
</div>
</div>
<div className=".col-xs-12 center text-center">
<Table responsive striped bordered hover>
<tr>
<th>Class 1</th>
<th>Class 2</th>
<th>Class 3</th>
<th>Class 4</th>
<th>Class 5</th>
</tr>
<tbody>
{this.getRows().map((row) => (
<tr key={row.reduce((a, b) => a + b)}>
{row.map((column) => (
<td key={column}>{column}</td>
))}
</tr>
))}
</tbody>
</Table>
</div>
</div>
</form>
);
}
}
export default App;
示例代码
const hits = [
{ name: 'Tammy', class: 'Class 1' },
{ name: 'Camen', class: 'Class 2' },
{ name: 'Happy', class: 'Class 3' },
{ name: 'Hello Kitty', class: 'Class 4' },
{ name: 'Hello Mimi', class: 'Class 3' },
];
const getRows = (hits) => {
const columns = ['Class 1', 'Class 2', 'Class 3', 'Class 4', 'Class 5'];
const rows = [];
const groupByColumn = hits.reduce((acc, next) => {
return { ...acc, [next.class]: [...(acc[next.class] || []), next.name] };
}, {});
const haveNames = () => columns.some((column) => (groupByColumn[column] || []).length > 0);
while (haveNames()) {
const newRow = columns.map((column) => {
return (groupByColumn[column] || []).shift() || '';
});
rows.push(newRow);
}
return rows;
};
const rows = getRows(hits);
console.log(rows);
推荐阅读
- assembly - 比较两个整数并尝试在 0x00400058 处执行非指令
- google-apps-script - 在特定文件夹中创建文件
- node.js - Node.Js 从 SQL Server 检索特定数据并将其编码为 JSON 数组
- node.js - readFileSync 在给出动态文件名时不返回缓冲区,但在给出静态文件名时给出结果
- php - Telegram API Bot - 对按钮触摸的回调查询响应
- visual-c++ - 无法启动移植到 VS 2019 的发布应用
- pandas - 如何将包含破折号(-)的两列相乘?
- javascript - 添加两列并在 HTML 表格的第三列中显示结果
- xquery - XQuery 表达式求值的示例不是顺序的
- java - 如何为链表添加方法将字符串输入对象(数组数组)?