首页 > 解决方案 > JavaScript:如何将具有嵌套数组的对象映射到 React 表

问题描述

我正在从 Firebase 中提取数据,并尝试使用 React 将其显示在表格中。

当我将数据数组记录到控制台时,我的数据如下所示:

Sampling0: {Time: "1575031318", Values: Array(6)}
Sampling1: {Time: "1575031965", Values: Array(6)}
Sampling2: {Time: "1575032607", Values: Array(6)}
Sampling3: {Time: "1575033253", Values: Array(6)}
Sampling4: {Time: "1575033926", Values: Array(6)}
Sampling5: {Time: "1575034577", Values: Array(6)}

以下是采样 1 的扩展数据:

Sampling1:
Time: "1575031965"
Values: Array(6)
Spot0: 31
Spot1: 32
Spot2: 7
Spot3: 32
Spot4: 11
Spot5: 18

我正在尝试将此数据映射到具有三列的表中,例如:

现货# | 价值 | 采样期

现货0 | 31 | 采样期 1

现货1 | 32 | 采样周期 1 <-- 然后移动到采样周期 2

现货0 | 42 | 采样期 2

现货1 | 41 | 采样期 2

到目前为止,这是我的代码:

componentDidMount() {
this.renderCharts();
};

renderCharts() {
  const wordRef = firebase.database().ref('myTable');
  wordRef.on('value', (snapshot) => {
    let words = snapshot.val().myData;
    let newState = [];
    let myState = [];
    for (let word in words) {
      newState.push({
        Time: word,
        Values: words[word],
      })
}

 render() {
    return (
      <div className="animated fadeIn">
                 <Table responsive>
                        <thead>
                        <tr>
                          <th>Spot #</th>
                          <th>Values</th>
                          <th>Sampling period</th>
                        </tr>
                        </thead>
                        <tbody>
                          {this.state.words.map((d, index) => {
                              return [
                                  <tr key={d.index}>
                                    <td>?</td>
                                    <td>{d.Values[index]}</td> //This grabs the value in the proper index but for different sampling periods
                                    <td>{index}</td> //This properly displays sampling period #'s
                                  </tr>
                              ];
                            })}

                        </tbody>
                      </Table>
      </div>

标签: javascriptarraysreactjs

解决方案


如果我理解正确,那么一种方法是使用 reduce预处理从 firebase 返回的数据,如下所示:

const data = {
    Sampling1: {Time: "1575031965", Values: [
        { Spot0: 31 },
        { Spot1: 32 },
        { Spot2: 7 },
        { Spot3: 32 },
        { Spot4: 11 },
        { Spot5: 18 }
    ]},
    Sampling2: {Time: "1575032607", Values: [
        { Spot0: 42 },
        { Spot1: 41 },
    ]},
    Sampling3: {Time: "1575033253", Values: [
        { Spot0: 1 },
        { Spot1: 2 },
        { Spot2: 3 }
    ]}
  };

const tableData = Object.entries(data).reduce((arr, samplingEntry) => {

  // Extract key and value of current sampling entry
  const [samplingKey, samplingObject] = samplingEntry;
  
  const smaplingPeroidLabel = samplingKey.replace('Sampling', 'Sampling period ');
  
  // Iterate first two spot items of Values array for sampling object
  for(let i = 0; i < Math.min(2, samplingObject.Values.length); i++) {
  
    // Extract the first entry of this spot object
    const [spotEntry] = Object.entries(samplingObject.Values[i]);
    
    // Extract key and value of this spot entry
    const [spotKey, spotValue] = spotEntry;
    
    // Add spot key, spot value and sampling key as new row of arr
    arr.push([ spotKey, spotValue, smaplingPeroidLabel ]);
  }

  return arr;

}, []);

console.log(tableData);

上面的脚本基本上将您的服务器响应转换为“数组数组”,其中每个子数组对应于您正在呈现的表中的一行数据。

在您的组件render()阶段,此数据将首先映射到<tr>元素,并且在二级映射中将该行元素的内容呈现为<td>元素,例如:

// Existing JSX
<tbody>
{ tableData.map(row => <tr>{ row.map(cell => <td>{ cell }</td> }</tr>) }
</tbody>
// Existing JSX

希望有帮助!


推荐阅读