0

I'm taking an intro to React course and just trying to accomplish something similar that I saw in my training. I'm trying to pull data from an API endpoint, make a little change to the data and then use setState to update the value of a variable that will hold the new data set.

The API returns a data set like this:

{
    "site1": [
      "device-a01",
      "device-a02",
      "device-b01",
      "device-b02"
    ],
    "site2": [
      "device-a01",
      "device-a02",
      "device-b01",
      "device-b02",
      "device-c01",
      "device-c02"
    ]
}

I need to iterate through this object and create an array variable that should look like this:

const tableData = [
    [
      "site1", "device-a01", 
      "site1", "device-a02",
      "site1", "device-b01", 
      "site1", "device-b02",
      "site2", "device-a01", 
      "site2", "device-a02",
      "site2", "device-b01", 
      "site2", "device-b02",
      "site2", "device-c01", 
      "site2", "device-c02"
    ]

My code:

import React from "react"

const [dataSet2, setDataSet2] = React.useState([])
  const [tableData, setTableData] = React.useState([])

  React.useEffect(() => {
    async function getData() {
      const res = await fetch("https://url.com/api/devices/")
      const data = await res.json()
      // console.log(JSON.stringify(data))
      setDataSet2(data)
    }
    getData()
  },[])


  Object.entries(dataSet2).map(([key, value]) => {
    value.map(hub => {
      buildTableData(key, hub)
    })
  })

  function buildTableData(key, value) {
    // console.log(key, value)
    const hubValue = key + "," + value
    console.log(hubValue) // prints the data to the console as i need it to be.

    // this causes the infinit loop error
    setTableData( prevData => ({
      ...prevData,
      hubValue
    }))
  }

I found some articles about this infinite loop error but they were pertaining to calling setState inside an event handler (example), not sure if it's related to what I'm trying to do, and if it is, then I don't know how to fix it code wise in my code.

stminion001
  • 333
  • 2
  • 15

2 Answers2

1

You need to build table data in useEffect. I advise you to prepare all data and update setDataSet2 and setTableData at the end:

import React from "react"

const [dataSet2, setDataSet2] = React.useState([])
const [tableData, setTableData] = React.useState([])

function buildTableData(key, value) {
  // console.log(key, value)
  const hubValue = key + "," + value
  console.log(hubValue) // prints the data to the console as i need it to be.

  return {
    ...prevData,
    hubValue
  }
}

React.useEffect(() => {
  async function getData() {
    const res = await fetch("https://url.com/api/devices/")
    const data = await res.json()
    
    const _tableData = Object.entries(data).map(([key, value]) => {
        return value.map(hub => buildTableData(key, hub)) // here is the fix
    })
    
    setTableData(_tableData);
    setDataSet2(data);
  }
  getData()
},[])

Fiodorov Andrei
  • 1,778
  • 1
  • 11
  • 26
1

I would try something like this:

import React from "react"

const [dataSet2, setDataSet2] = React.useState([])
const [tableData, setTableData] = React.useState([])

React.useEffect(() => {
    fetch("https://url.com/api/devices/").then(res => setDataSet2(res.data))
}, [])

React.useEffect(() => {
    if (!tableData) {
        let results = []
        Object.entries(dataSet2).map(([key, value]) => {
            return value.map(hub => {
                results.push(key)
                results.push(hub)
            })
        })
        setTableData(results)
    }
}, [dataSet2])
Sylvain
  • 509
  • 1
  • 7
  • 17