简体   繁体   中英

JavaScript: How to map object with nested arrays to table for React

I am pulling data from Firebase and I am trying to display it in a table with React.

Here is what my data looks like when I log the data array to the console:

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)}

Here is what the expanded data looks like for sampling1:

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

I am trying to map this data into a table with three columns for example:

Spot # | Value | Sampling Period

Spot 0 | 31 | Sampling Period 1

Spot 1 | 32 | Sampling period 1 <-- Then move to sampling period 2

Spot 0 | 42 | Sampling Period 2

Spot 1 | 41 | Sampling period 2

Here's my code so far:

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>

If I understand correctly then one approach would be to preprocess the data returned from firebase using reduce as shown below:

 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);

The script above basically transforms your server response to an "array of arrays", where each sub array corresponds to a row of data in the table that you are rendering.

During your components render() phase, this data would first be mapped to <tr> elements and, where a secondary mapping would render the contents of that row element into <td> elements, eg:

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

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM